Go中的Os Exec Sudo命令


Os Exec Sudo Command in Go

在熟悉Go和goroutine的过程中,我遇到了执行命令的障碍。这些命令的格式为:

1
sudo find /folder -type f | while read i; do sudo -S chmod 644"$i"; done

使用从如何在Golang中执行系统命令(带有未知参数)中获取的代码,我正在尝试执行此命令,但我相信由于第一个参数为sudo而未执行,这可能是错误的。我只有两个问题。

当这些命令无法运行时,我将返回"退出状态1",是否有比我正在做的事情更详细的错误信息?问题二,为什么我使用此脚本会获得"退出状态1"?这是怎么回事?

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package main

import (
   "bufio"
   "fmt"
   "os"
   "os/exec"
   "strings"
   "sync"
)

func ExeCmd(cmd string, wg *sync.WaitGroup) {
    parts := strings.Fields(cmd)
    head := parts[0]
    // Head at this point is"sudo"
    parts = parts[1:len(parts)]
    out, err := exec.Command(head,parts...).Output()
    if err != nil {
        fmt.Printf("%s\
", err)
    }
    fmt.Printf("%s\
", out)
    wg.Done() // Signal to WaitGroup goroutine finished
}

func InArray(a []string, e string) bool {
    for _, x := range a {
        if x == e {
            return true
            fmt.Print("True")
        }
    }
    return false
}

func main() {
    exec.Command("sudo ls > /dev/null") // Get sudo password just once, doesn't seem to work with Go
    wg := new(sync.WaitGroup)
    reader := bufio.NewReader(os.Stdin)
    fdbslices := []string{"f","d","b","files","directories","both"}
    commands := []string{}
    fdb :=""
    filep :=""
    dirp :=""

    // Grab Path
    fmt.Print("Path:")
    findpath, _ := reader.ReadString('\
')
    findpath = strings.ToLower(strings.Trim(findpath,"\
"))

    // Grab Files, Directories, or Both
    for {
        fmt.Print("Files, Directories, or Both:")
        fdb, _ = reader.ReadString('\
')
        fdb = strings.ToLower(strings.Trim(fdb,"\
"))
        if InArray(fdbslices, fdb) == true { break }
    }

    // Build commands string, these come out as they should
    for {
        if fdb =="f" || fdb =="files" {
            fmt.Print("Permissions for Files:")
            filep, _ = reader.ReadString('\
')
            filep = strings.Trim(filep,"\
")
            commands = append(commands,"sudo find" + findpath +" -type f | while read i; do sudo -S chmod" + filep +" "$i"; done")
        }
        if fdb =="d" || fdb =="directories" {
            fmt.Print("Permissions for Directories:")
            dirp, _ = reader.ReadString('\
')
            dirp = strings.Trim(dirp,"\
")
            commands = append(commands,"sudo find" + findpath +" -type d | while read i; do sudo -S chmod" + dirp +" "$i"; done")
        }
        if fdb =="b" || fdb =="both" {
            fmt.Print("Permissions for Files:")
            filep, _ = reader.ReadString('\
')
            filep = strings.Trim(filep,"\
")
            commands = append(commands,"sudo find" + findpath +" -type f | while read i; do sudo -S chmod" + filep +" "$i"; done")
            fmt.Print("Permissions for Directories:")
            dirp, _ = reader.ReadString('\
')
            dirp = strings.Trim(dirp,"\
")
            commands = append(commands,"sudo find" + findpath +" -type d | while read i; do sudo -S chmod" + dirp +" "$i"; done")
        }
        break
    }

    // Execute Commands
    for _, str := range commands {
        wg.Add(1)
        fmt.Print("Doing:" + str +"\
\
")
        go ExeCmd(str, wg)
    }

    wg.Wait()
}

示例终端输出:

1
2
3
4
5
6
7
8
9
Path: test
Files, Directories, or Both: b
Permissions for Files: 644
Permissions for Directories: 755
Doing: find test -type f | while read i; do sudo -S chmod 644"$i"; done
Doing: find test -type d | while read i; do sudo -S chmod 755"$i"; done
exit status 1

exit status 1

谢谢您的时间。


exec.Command()将要求内核直接执行给定的进程。但是,您传递的命令是由外壳程序脚本链接在一起的多个程序的字符串。

如果要执行Shell脚本,则应使用以下内容:

1
cmd := exec.Command("/bin/sh","-c","sudo find ...")