英文:
Os Exec Sudo Command in Go
问题
在熟悉Go和goroutines的过程中,我在执行命令时遇到了一个问题。这些命令的格式如下:
sudo find /folder -type f | while read i; do sudo -S chmod 644 "$i"; done
我尝试执行这个命令,但我认为它没有执行成功,可能是因为第一个参数是sudo,但我可能错了。我只有两个问题。
当这些命令无法运行时,我得到的返回值是"exit status 1",有没有办法获得比我目前做的更详细的错误信息?第二个问题是,为什么我会得到"exit status 1"的返回值?这个脚本出了什么问题?
谢谢你的时间。
英文:
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 https://stackoverflow.com/questions/20437336/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\n", err)
}
fmt.Printf("%s\n", 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('\n')
findpath = strings.ToLower(strings.Trim(findpath, "\n"))
// Grab Files, Directories, or Both
for {
fmt.Print("Files, Directories, or Both: ")
fdb, _ = reader.ReadString('\n')
fdb = strings.ToLower(strings.Trim(fdb, "\n"))
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('\n')
filep = strings.Trim(filep, "\n")
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('\n')
dirp = strings.Trim(dirp, "\n")
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('\n')
filep = strings.Trim(filep, "\n")
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('\n')
dirp = strings.Trim(dirp, "\n")
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 + "\r\n")
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
得分: 27
exec.Command()
会要求内核直接执行给定的进程。然而,你传递的命令是一个由shell脚本连接在一起的多个程序的字符串。
如果你想执行一个shell脚本,你应该使用类似这样的方式:
cmd := exec.Command("/bin/sh", "-c", "sudo find ...")
英文:
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 ...")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论