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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
package loginshell
import (
"errors"
"fmt"
"os"
"os/exec"
"os/user"
"regexp"
"runtime"
"strings"
)
func Shell() (string, error) {
switch runtime.GOOS {
case "plan9":
return Plan9Shell()
case "linux":
return NixShell()
case "openbsd":
return NixShell()
case "freebsd":
return NixShell()
case "darwin":
return DarwinShell()
case "windows":
return WindowsShell()
}
return "", errors.New("Undefined GOOS: " + runtime.GOOS)
}
func Plan9Shell() (string, error) {
if _, err := os.Stat("/dev/osversion"); err != nil {
if os.IsNotExist(err) {
return "", err
} else {
return "", errors.New("/dev/osversion check failed")
}
}
return "/bin/rc", nil
}
func WindowsShell() (string, error) {
consoleApp := os.Getenv("COMSPEC")
if consoleApp == "" {
consoleApp = "cmd.exe"
}
return consoleApp, nil
}
func NixShell() (string, error) {
user, err := user.Current()
if err != nil {
return "", err
}
out, err := exec.Command("getent", "passwd", user.Uid).Output()
if err != nil {
return "", err
}
ent := strings.Split(strings.TrimSuffix(string(out), "\n"), ":")
return ent[6], nil
}
func DarwinShell() (string, error) {
dir := "Local/Default/Users/" + os.Getenv("USER")
out, err := exec.Command("dscl", "localhost", "-read", dir, "UserShell").Output()
if err != nil {
return "", err
}
re := regexp.MustCompile("UserShell: (/[^ ]+)\n")
matched := re.FindStringSubmatch(string(out))
shell := matched[1]
if shell == "" {
return "", errors.New(fmt.Sprintf("Invalid output: %s", string(out)))
}
return shell, nil
}
|