dtgta48604 2014-06-07 09:11
浏览 420
已采纳

Go中的Os Exec Sudo命令

In the process of familiarizing myself with Go and goroutines I have hit a road block with executing commands. The format of these commands are:

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

With code taken from How to execute system command in Golang with unknown arguments I'm trying to execute this command but I believe it's not executing due to the first argument being sudo, I could be wrong. I have just two questions.

When these commands fail to run I am returned "exit status 1", is there a way to get a more detailed error than what I am doing? Question two, why would I be getting "exit status 1" with this script? What is going on that isn't supposed to?

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()
}

Example Terminal output:

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

Thank you for your time.

  • 写回答

1条回答 默认 最新

  • doujingya1166 2014-06-07 09:55
    关注

    exec.Command() will ask the kernel to execute the given process directly. However, the command you are passing is a string of multiple programs hooked together by a shell script.

    If you want to execute a shell script, you should use something like this:

    cmd := exec.Command("/bin/sh", "-c", "sudo find ...")
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题