80 lines
1.7 KiB
Go
80 lines
1.7 KiB
Go
package termenv
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/gookit/goutil/internal/checkfn"
|
|
"github.com/gookit/goutil/internal/comfunc"
|
|
"golang.org/x/term"
|
|
)
|
|
|
|
var (
|
|
cmdList = []string{"cmd", "cmd.exe"}
|
|
pwshList = []string{"powershell", "powershell.exe", "pwsh", "pwsh.exe"}
|
|
)
|
|
|
|
// IsTerminal 检查是否为终端设备中
|
|
func IsTerminal() bool {
|
|
fd := int(os.Stdout.Fd())
|
|
return term.IsTerminal(fd)
|
|
}
|
|
|
|
// CurrentShell get current used shell env file.
|
|
//
|
|
// eg "/bin/zsh" "/bin/bash".
|
|
// if onlyName=true, will return "zsh", "bash"
|
|
func CurrentShell(onlyName bool, fallbackShell ...string) string {
|
|
return comfunc.CurrentShell(onlyName, fallbackShell...)
|
|
}
|
|
|
|
// HasShellEnv has shell env check.
|
|
//
|
|
// Usage:
|
|
//
|
|
// HasShellEnv("sh")
|
|
// HasShellEnv("bash")
|
|
func HasShellEnv(shell string) bool {
|
|
// can also use: "echo $0"
|
|
out, err := shellExec("echo OK", shell)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return strings.TrimSpace(out) == "OK"
|
|
}
|
|
|
|
// IsShellSpecialVar reports whether the character identifies a special
|
|
// shell variable such as $*.
|
|
func IsShellSpecialVar(c uint8) bool {
|
|
switch c {
|
|
case '*', '#', '$', '@', '!', '?', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func shellExec(expr, shell string) (string, error) {
|
|
// "-c" for bash,sh,zsh shell
|
|
mark := "-c"
|
|
if shell == "" {
|
|
shell = CurrentShell(true, "sh")
|
|
}
|
|
|
|
// special for Windows shell
|
|
if runtime.GOOS == "windows" {
|
|
// use cmd.exe, mark is "/c"
|
|
if checkfn.StringsContains(cmdList, shell) {
|
|
mark = "/c"
|
|
} else if checkfn.StringsContains(pwshList, shell) {
|
|
// "-Command" for powershell
|
|
mark = "-Command"
|
|
}
|
|
}
|
|
|
|
cmd := exec.Command(shell, mark, expr)
|
|
bs, err := cmd.CombinedOutput()
|
|
return string(bs), err
|
|
}
|