package
1.15.1
Repository: https://github.com/qiniu/x.git
Documentation: pkg.go.dev

# README

gsh - An alternative to write shell scripts

Language GitHub release Discord GoDoc

This is an alternative to write shell scripts.

Yes, now you can write shell script in XGo. It supports all shell commands.

Usage

First, let's create a file named example.gsh and write the following code:

mkdir "testgsh"

You don't need a go.mod file, just enter gop run ./example.gsh directly to run.

It's strange to you that the file extension of XGo source is not .xgo but .gsh. It is only because XGo register .gsh as a builtin classfile.

We can change example.gsh more complicated:

type file struct {
	name  string
	fsize int
}

mkdir! "testgsh"

mkdir "testgsh2"
lastErr!

mkdir "testgsh3"
if lastErr != nil {
	panic lastErr
}

capout => { ls }
echo output.fields

capout => { ls "-l" }
files := [file{flds[8], flds[4].int!} for e <- output.split("\n") if flds := e.fields; flds.len > 2]
echo files

rmdir "testgsh", "testgsh2", "testgsh3"

Execute shell commands

There are many ways to execute shell commands. The simplest way is:

mkdir "testgsh"

It is equivalent to:

exec "mkdir", "testgsh"

or:

exec "mkdir testgsh"

If a shell command is a Go/XGo language keyword (eg. go), or the command is a relative or absolute path, you can only execute it in the latter two ways:

exec "go", "version"
exec "./test.sh"
exec "/usr/bin/env gop run ."

You can also specify environment variables to run:

exec "GOOS=linux GOARCH=amd64 go install ."

Retrieve environment variables

You can get the value of an environment variable through ${XXX} or $XXX. For example:

echo ${HOME}
ls $HOME

You can also use exec command through $XXX:

exec "ls $HOME"

Check last error

If we want to ensure mkdir successfully, there are three ways:

The simplest way is:

mkdir! "testsh"  # will panic if mkdir failed

The second way is:

mkdir "testsh"
lastErr!

Yes, gsh provides lastErr to check last error.

The third way is:

mkdir "testsh"
if lastErr != nil {
    panic lastErr
}

This is the most familiar way to Go developers.

Capture output of commands

And, gsh provides a way to capture output of commands:

capout => {
    ...
}

Similar to lastErr, the captured output result is saved to output.

For example:

capout => { ls "-l" }
echo output

Here is a possible output:

total 72
-rw-r--r--  1 xushiwei  staff  11357 Jun 19 00:20 LICENSE
-rw-r--r--  1 xushiwei  staff    127 Jun 19 10:00 README.md
-rw-r--r--  1 xushiwei  staff    365 Jun 19 00:25 example.gsh
-rw-r--r--  1 xushiwei  staff    126 Jun 19 09:33 go.mod
-rw-r--r--  1 xushiwei  staff    165 Jun 19 09:33 go.sum
-rw-r--r--  1 xushiwei  staff   1938 Jun 19 10:00 gop_autogen.go

We can use XGo powerful built-in data processing capabilities to process captured output:

type file struct {
	name  string
	fsize int
}

files := [file{flds[8], flds[4].int!} for e <- output.split("\n") if flds := e.fields; flds.len > 2]

In this example, we split output by "\n", and for each entry e, split it by spaces (e.fields) and save into flds. Condition flds.len > 2 is to remove special line of output:

total 72

At last, pick file name and size of all selected entries and save into files.