# README
gsh - An alternative to write shell scripts
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
.