diff --git a/system/os.go b/system/os.go index 5b63c07..5146c2c 100644 --- a/system/os.go +++ b/system/os.go @@ -9,6 +9,10 @@ import ( "os" "os/exec" "runtime" + "unicode/utf8" + + "github.com/duke-git/lancet/v2/validator" + "golang.org/x/text/encoding/simplifiedchinese" ) // IsWindows check if current os is windows @@ -50,27 +54,61 @@ func CompareOsEnv(key, comparedEnv string) bool { return env == comparedEnv } -// ExecCommand use shell /bin/bash -c to execute command +// ExecCommand execute command, return the stdout and stderr string of command, and error if error occur +// param `command` is a complete command strinig, like, ls -a (linux), dir(windows), ping 127.0.0.1 +// for linux, use /bin/bash -c to execute command +// for windows, use powershell.exe to execute command func ExecCommand(command string) (stdout, stderr string, err error) { var out bytes.Buffer - var errout bytes.Buffer + var errOut bytes.Buffer cmd := exec.Command("/bin/bash", "-c", command) if IsWindows() { - cmd = exec.Command("cmd") + cmd = exec.Command("powershell.exe", command) } cmd.Stdout = &out - cmd.Stderr = &errout + cmd.Stderr = &errOut + err = cmd.Run() if err != nil { - stderr = string(errout.Bytes()) + if utf8.Valid(errOut.Bytes()) { + stderr = byteToString(errOut.Bytes(), "UTF8") + } else if validator.IsGBK(errOut.Bytes()) { + stderr = byteToString(errOut.Bytes(), "GBK") + } + return + } + + data := out.Bytes() + if utf8.Valid(data) { + stdout = byteToString(data, "UTF8") + } else if validator.IsGBK(data) { + stdout = byteToString(data, "GBK") } - stdout = string(out.Bytes()) return } +func byteToString(data []byte, charset string) string { + var result string + + switch charset { + case "GBK": + decodeBytes, _ := simplifiedchinese.GBK.NewDecoder().Bytes(data) + result = string(decodeBytes) + case "GB18030": + decodeBytes, _ := simplifiedchinese.GB18030.NewDecoder().Bytes(data) + result = string(decodeBytes) + case "UTF8": + fallthrough + default: + result = string(data) + } + + return result +} + // GetOsBits get this system bits 32bit or 64bit // return bit int (32/64) func GetOsBits() int { diff --git a/system/os_test.go b/system/os_test.go index 694c33c..a21cbd9 100644 --- a/system/os_test.go +++ b/system/os_test.go @@ -11,10 +11,10 @@ func TestOsDetection(t *testing.T) { assert := internal.NewAssert(t, "TestOsJudgment") osType, _, _ := ExecCommand("echo $OSTYPE") - if strings.Index(osType, "linux") != -1 { + if strings.Contains(osType, "linux") { assert.Equal(true, IsLinux()) } - if strings.Index(osType, "darwin") != -1 { + if strings.Contains(osType, "darwin") { assert.Equal(true, IsMac()) } } @@ -44,21 +44,27 @@ func TestOsEnvOperation(t *testing.T) { func TestExecCommand(t *testing.T) { assert := internal.NewAssert(t, "TestExecCommand") - out, errout, err := ExecCommand("ls") - t.Log("std out: ", out) - t.Log("std err: ", errout) + // linux or mac + stdout, stderr, err := ExecCommand("ls") + t.Log("std out: ", stdout) + t.Log("std err: ", stderr) + assert.Equal("", stderr) assert.IsNil(err) - out, errout, err = ExecCommand("abc") - t.Log("std out: ", out) - t.Log("std err: ", errout) - if err != nil { - t.Logf("error: %v\n", err) - } + // windows + stdout, stderr, err = ExecCommand("dir") + t.Log("std out: ", stdout) + t.Log("std err: ", stderr) + assert.IsNil(err) - if !IsWindows() { - assert.IsNotNil(err) - } + // error command + stdout, stderr, err = ExecCommand("abc") + t.Log("std out: ", stdout) + t.Log("std err: ", stderr) + // if err != nil { + // t.Log(err.Error()) + // } + assert.IsNotNil(err) } func TestGetOsBits(t *testing.T) {