各位 golang 大佬(爹),上午好!我有个菜鸡问题:如何使用 golang 的 exec.Command()函数执行 sudo ?
背景:小弟在使用 chromedp 做一个爬虫,目前一切正常,唯一的遗憾就是每次运行之前需要手动在 macOS 的终端执行 sudo /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=19222
必须加 sudo 才能打开 chrome 调试窗口。因为 golang 可以执行终端命令,所以我想使用代码去唤醒调试窗口,但是测试下来好像无法全自动调用 sudo 命令(不输入密码或密码怎么传进去)。
1
NessajCN 248 天前 2
你用 sudo 执行爬虫程序不就好了
|
2
imPrk 248 天前
cmd := exec.Command("sudo", "ls", "/root")
|
4
pkoukk 248 天前
go build -o main .
sudo ./main |
6
fengxsong 248 天前
你把运行用户的 sudo 设置 NOPASSWD 不就行了嘛。。
|
8
JEME 248 天前
使用 pty 相关的库,应该可以?
|
9
aloxaf 248 天前
用 sudo -S 可以从标准输入接收密码,然后你就可以正常把密码传进去了
|
10
yanghanlin 248 天前 via Android
sudo -S 然后密码通过 stdin 传进去?
|
11
eber OP @NessajCN 抱歉,抱歉。。。找到问题了,确实 sudo 运行程序可以唤醒调试页面。应该是 chrome 路径问题。。。/Applications/Google Chrome.app/Contents/MacOS/Google Chrome 空格不能加转译。。。
|
12
Yangsh853 248 天前
在 sudoers 给用户加 NOPASSWD ,就不用输密码了
|
15
eber OP |
16
somebody1 248 天前 2
这是学到精髓了呀,上周的那个帖子上大分!
|
17
wOuv7i4e7XxsSOR1 248 天前
sudo -A
|
18
proxychains 248 天前 via Android
提问的艺术
|
19
cat9life 248 天前
辈分有点乱啊,一会爹一会自称小弟。(开个玩笑..
|
20
lele140 248 天前
|
21
deplives 248 天前
sudo 可以使用 -S 从 stdin 传入密码
|
23
chanChristin 248 天前
提问的艺术得更新了
|
24
2Nfree 248 天前
golang.org/x/crypto/ssh 包可以创建标准管道输出
用 session.StdinPipe() |
25
2Nfree 248 天前
@2Nfree 用这个办法可以输入 sudo 的密码,之前写过一个模仿 ansiable 的程序是这么做的,里面部分代码:
package utils import ( "batch-execution-tool/core" "bytes" "fmt" "golang.org/x/crypto/ssh" "os" "sync" ) func ExecuteScripts() { var wg sync.WaitGroup defer wg.Wait() for _, ip := range core.Config.ServersIP { wg.Add(1) go func(ip string) { defer wg.Done() SSHClient, errSSH := createSSHConnect(ip) if errSSH != nil { core.Logger.Sugar().Errorf("创建 SSH 链接失败:\n%v", errSSH) return } for _, script := range core.Config.Scripts { for name := range script { err := exec(SSHClient, ip, name) if err != nil { core.Logger.Sugar().Errorf("在 IP 地址为:%v 的服务器,出现错误:\n%v", ip, err) } else { core.Logger.Sugar().Debugf("在 IP 地址为:%v 的服务器,执行脚本 %v 成功", ip, name) } } } }(ip) } } func exec(client *ssh.Client, ip, script string) error { core.Logger.Sugar().Debugf("正在 IP 地址为:%v 的服务器中执行脚本:%s", ip, script) session, err := client.NewSession() if err != nil { return err } var output bytes.Buffer session.Stderr = &output remoteDir := "scripts" if core.Config.Auth.Username == "root" { if err := session.Start("bash " + remoteDir + "/" + script + " > " + remoteDir + "/" + script + ".log"); err != nil { return fmt.Errorf("执行脚本 %s 失败: \n%s:%s", script, err, output.String()) } if err := session.Wait(); err != nil { return fmt.Errorf("执行脚本 %s 失败: \n%s:%s", script, err, output.String()) } } else { if err := session.RequestPty("xterm", 80, 40, ssh.TerminalModes{}); err != nil { return fmt.Errorf("请求 TTY 出错:%v ,\nos.Stderr:%v", err, os.Stderr) } stdin, err := session.StdinPipe() defer stdin.Close() if err != nil { return fmt.Errorf("创建标准管道输出错误: \n%v", err) } if err := session.Start("sudo bash " + remoteDir + "/" + script + " > " + remoteDir + "/" + script + ".log"); err != nil { return fmt.Errorf("执行脚本 %s 失败: \n%s:%s", script, err, output.String()) } _, err = fmt.Fprintln(stdin, core.Config.Auth.Password) if err != nil { return fmt.Errorf("使用标准管道输如密码错误: \n%v", err) } if err := session.Wait(); err != nil { return fmt.Errorf("执行脚本 %s 失败: \n%s:%s", script, err, output.String()) } } session.Close() return nil } |
26
eber OP |
27
danhahaha 248 天前
连续俩帖子把我震住了,态度如此诚恳,此子必成大器
|
28
danbai 247 天前 via Android
哥们都用 golang 了你可以用用 rod 这个库
|