Skip to content

Instantly share code, notes, and snippets.

@danielhe4rt
Created October 10, 2024 18:26
Show Gist options
  • Save danielhe4rt/05f5b205e4399d8f376b2bc59620b345 to your computer and use it in GitHub Desktop.
Save danielhe4rt/05f5b205e4399d8f376b2bc59620b345 to your computer and use it in GitHub Desktop.
3h of golang and some weird malfunctioned shell
package main
import (
"bufio"
"fmt"
"github.com/codecrafters-io/shell-starter-go/cmd/myshell/commands"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
)
func main() {
// Uncomment this block to pass the first stage
for {
fmt.Fprint(os.Stdout, "$ ")
// Wait for user input
input, _ := bufio.NewReader(os.Stdin).ReadString('\n')
rawArgs := strings.Split(strings.Trim(input, "\n"), " ")
cmd := rawArgs[0]
args := make([]string, 0)
if len(rawArgs) > 1 {
args = rawArgs[1:]
}
switch cmd {
case "echo":
fmt.Printf("%v\n", strings.Join(args, " "))
break
case "exit":
exitStatus := 0
if len(args) >= 1 {
exitStatus, _ = strconv.Atoi(args[0])
}
os.Exit(exitStatus)
case "type":
commandOutput := args[0] + ": not found"
paths := strings.Split(os.Getenv("PATH"), ":")
for _, path := range paths {
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.Name() == args[0] {
commandOutput = args[0] + " is " + path
}
return nil
})
if err != nil {
// TODO: error handling ???
}
}
for _, command := range commands.CommandsAvailable() {
if command == args[0] {
commandOutput = args[0] + " is a shell builtin"
break
}
}
fmt.Fprintln(os.Stdout, commandOutput)
break
default:
paths := strings.Split(os.Getenv("PATH"), ":")
commandExecuted := false
for _, path := range paths {
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.Name() == cmd {
var cmdStruct *exec.Cmd
if len(args) > 0 {
cmdStruct = exec.Command(path, args...)
} else {
cmdStruct = exec.Command(path)
}
out, err := cmdStruct.Output()
if err != nil {
return err
}
fmt.Print(string(out))
commandExecuted = true
}
return nil
})
if err != nil {
// TODO: error handling ???
}
}
if !commandExecuted {
fmt.Fprintf(os.Stdout, "%s: command not found\n", cmd)
}
break
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment