Go Shell
I have recently made a shell in go, link to its source code.
Basic code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
| package main
import (
"bufio"
"fmt"
"os"
"os/exec"
"os/signal"
"runtime"
"strings"
)
func main() {
if runtime.GOOS == "windows" {
fmt.Println("Shell is not made for windows. Sorry")
os.Exit(1)
}
reader := bufio.NewReader(os.Stdin)
for {
wd, err := os.Getwd()
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
fmt.Print(wd)
fmt.Print(" $ ")
input, err := reader.ReadString('\n')
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
if err = execInput(input); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
}
func execInput(input string) error {
home := os.Getenv("HOME")
input = strings.TrimSuffix(input, "\n")
args := strings.Split(input, " ")
switch args[0] {
case "exit":
os.Exit(0)
case "cd":
if len(args) < 2 {
return os.Chdir(home)
}
return os.Chdir(args[1])
}
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
|
Don’t worry, we’ll go over the code
Code explanation
Check if running on windows
1
2
3
4
| if runtime.GOOS == "windows" {
fmt.Println("Shell is not made for windows. Sorry")
os.Exit(1)
}
|
This checks if it is running on windows. If it is, it exits with error.
Create reader
1
| reader := bufio.NewReader(os.Stdin)
|
This allows us to read from the standard input.
Read loop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| for {
wd, err := os.Getwd()
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
fmt.Print(wd)
fmt.Print(" $ ")
input, err := reader.ReadString('\n')
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
if err = execInput(input); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
|
This reads from the standard input and executes the input.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| func execInput(input string) error {
home := os.Getenv("HOME")
input = strings.TrimSuffix(input, "\n")
args := strings.Split(input, " ")
switch args[0] {
case "exit":
os.Exit(0)
case "cd":
if len(args) < 2 {
return os.Chdir(home)
}
return os.Chdir(args[1])
}
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
|
This executes the input.
1
2
3
4
5
6
7
8
9
| switch args[0] {
case "exit":
os.Exit(0)
case "cd":
if len(args) < 2 {
return os.Chdir(home)
}
return os.Chdir(args[1])
}
|
This switch statement adds commands that don’t have a binary.
Conclusion
This is a shell in go.
Obviously it can be modified to add commands and customize it.