func CdCmd(scp *variables.Scope, ioc *T.IOContainer, args []string) T.ExitStatus { // This does not conform to the posix spec. // Very simplified. Cd to first arg or attempt to cd to home dir cdTarget := "." if len(args) == 0 { homeDir := scp.Get("HOME") if homeDir.Val == "" { // Implementation defined behaviour. We try to grab // the homedir of the current user u, err := user.Current() if err == nil { cdTarget = u.HomeDir } } else { cdTarget = homeDir.Val } } else { cdTarget = args[0] } if err := scp.SetPwd(cdTarget); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return T.ExitFailure } return T.ExitSuccess }
func (s SubVariable) Sub(scp *variables.Scope) (returnString string) { logex.Debug("Substituting variable") defer func() { logex.Debugf("Returned '%s'", returnString) }() v := scp.Get(s.VarName) switch s.SubType { case VarSubNormal: return v.Val case VarSubLength: // For the values ${#*} and ${#@} // the number of positional parameters is returned // We need to perform IFS splitting to figure this out return strconv.Itoa(len(v.Val)) } varExists := v.Set == true // CheckNull means that an empty string is treated as unset if s.CheckNull { varExists = varExists && v.Val != "" } switch s.SubType { case VarSubAssign: if varExists { return v.Val } scp.Set(s.VarName, s.SubVal) return s.SubVal case VarSubMinus: if varExists { return v.Val } return s.SubVal case VarSubPlus: if varExists { return "" } return s.SubVal case VarSubQuestion: if varExists { return v.Val } if s.SubVal != "" { ExitShellWithMessage(T.ExitFailure, s.SubVal) } ExitShellWithMessage(T.ExitFailure, s.VarName+": Parameter not set") case VarSubTrimRight, VarSubTrimRightMax, VarSubTrimLeft, VarSubTrimLeftMax: ExitShellWithMessage(T.ExitFailure, "Trim operations not implemented") } logex.Fatal("SubVariable.Sub unreached") return "" }
func LocalCmd(scp *variables.Scope, ioc *T.IOContainer, args []string) T.ExitStatus { // Local should also do assignments, split args on equal sign? already // expanded for _, a := range args { tmp := scp.Get(a) if tmp.Set { scp.Set(a, tmp.Val, variables.LocalScope) } else { scp.Set(a, "", variables.LocalScope) } } return T.ExitSuccess }