Files
shell/main.go
2023-11-06 21:15:17 +01:00

94 lines
1.7 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"os/exec"
"strings"
"unicode"
)
func main() {
// Load the configuration file, if any
// Run command loop
myshell_loop()
// Perform any shutdown/cleanup
}
func myshell_loop() {
for {
// Read command
fmt.Printf("myshell> ")
line := read_line()
// Parse command
args := split_line(line)
// Execute command
output, err := execute(args)
if err != nil {
fmt.Println("error during exec command:", err)
} else {
fmt.Printf(string(output))
}
}
// Loop back to read command
}
func read_line() string {
// Read the command line
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Error reading command line: ", err)
}
// Remove the newline character
input = strings.TrimSuffix(input, "\r\n")
input = strings.TrimSuffix(input, "\n")
return input
}
// Split the line into arguments
func split_line(line string) []string {
fieldSeparator := func(c rune) bool {
return unicode.IsSpace(c) || c == '\a'
}
args := strings.FieldsFunc(line, fieldSeparator)
return args
}
var builtin_cmds = map[string]func([]string) ([]byte, error){
"cd": myshell_cd,
"exit": myshell_exit,
}
// Execute the command
func execute(args []string) ([]byte, error) {
// Check for builtin commands
if cmd, ok := builtin_cmds[args[0]]; ok {
return cmd(args)
}
cmd := exec.Command("sh", "-c", strings.Join(args, " "))
output, err := cmd.CombinedOutput()
return output, err
}
func myshell_cd(args []string) ([]byte, error) {
if len(args) < 2 {
return nil, fmt.Errorf("cd: missing argument")
}
err := os.Chdir(args[1])
return nil, err
}
func myshell_exit(args []string) ([]byte, error) {
os.Exit(0)
return nil, nil
}