package command import ( "bbash/command/cat" "bbash/command/cd" "bbash/command/cp" "bbash/command/echo" "bbash/command/head" "bbash/command/help" "bbash/command/ls" "bbash/command/man" "bbash/command/mv" "bbash/command/pwd" "bbash/command/rm" "bbash/command/touch" "bbash/environment" "bbash/input_parser" "fmt" "os" "os/exec" "path/filepath" "strings" ) var path_command map[string]string func Init(env *environment.Env) { path_command = make(map[string]string) init_path(env) } func Run_command(in input_parser.Input, env *environment.Env) { switch in.Instruction { case "pwd": pwd.Pwd(in, env) case "echo": echo.Echo(in, env) case "ls": ls.Ls(in, env) case "cd": cd.Cd(in, env) case "man": man.Man(in, env) case "cat": cat.Cat(in, env) case "head": head.Head(in, env) case "touch": touch.Touch(in, env) case "rm": rm.Rm(in, env) case "cp": cp.Cp(in, env) case "mv": mv.Mv(in, env) case "help": help.Help(in, env) default: if !run_by_path(in, env) { fmt.Println(fmt.Sprintf("No such command! (%s)", in.Instruction)) } } } // Returns if anything was run or not func run_by_path(in input_parser.Input, env *environment.Env) bool { instr, errB := path_command[in.Instruction] if !errB { return false } cmd := exec.Command(instr, strings.Fields(in.Args_raw)...) output, _ := cmd.CombinedOutput() print(string(output)) return true } func init_path(env *environment.Env) { path := strings.Split(env.Env["PATH"], ":") for _, a_path := range path { recursive_executable_finder(a_path) } } func recursive_executable_finder(path string) { dir, err := os.ReadDir(path) if err != nil { return } for _, f := range dir { if f.IsDir() { recursive_executable_finder(f.Name()) continue } if !is_executable(f.Name()) { continue } path_command[f.Name()] = filepath.Join(path, f.Name()) } } func is_executable(name string) bool { return true stat, _ := os.Stat(name) mode := stat.Mode() return mode&(1<<0) != 0 || // Others' execute bit mode&(1<<3) != 0 || // Group's execute bit mode.Perm()&(1<<6) != 0 // Owner's execute bit }