执行脚本和命令(bash,csh)
go exec.Command()
01,bash支持~路径,csh(好像)不支持,所以测试时使用全路径
02,csh_script是csh脚本(#!/bin/csh开头),内容:chmod +x /home/e0004495/tmp/test_chmod
1 | 不需返回值 bash csh |
不需返回值:运行命令:bash,报错会反馈error,(比如文件不存在)
1 | cmd := exec.Command("bash","-c","chmod +x /home/e0004495/tmp/test_chmod") |
不需返回值:运行命令:csh,报错会反馈error,(比如文件不存在)
1 | cmd := exec.Command("csh","-c","chmod +x /home/e0004495/tmp/test_chmod") |
不需返回值:运行脚本:bash,报错会反馈error,(比如文件不存在)
1 | in := bytes.NewBuffer(nil) |
不需返回值:运行脚本:csh,报错不会反馈error,(比如文件不存在,脚本内容也不会执行)
1 | in := bytes.NewBuffer(nil) |
可见部分操作bash可行,而csh不行。并且也不会报错。给人感觉是被正确执行了。
网上很多资料也都是针对bash的,直接迁移到csh就会有问题。
尤其注意,有些命令,不会报错,但实际脚本并不会被执行,这基本可以看做天坑了。很多研发并未养成测试错误case的习惯
csh采用下面方法是可行的。
1 | cmd :=exec.Command("/home/e0004495/tmp/csh_script") |
这样也行
1 | cmd :=exec.Command("/bin/csh","/home/e0004495/tmp/csh_script") |
脚本执行,csh,回显命令结果
1 | cmd :=exec.Command("/bin/csh","/home/e0004495/tmp/csh_script") |
需要返回值的情况,用到再补充,放几篇文章
golang exec.Command 执行命令用法实例:https://blog.csdn.net/whatday/article/details/109277998
sudo密码输入问题
问题如下:使用go command执行shell命令,命令需要sudo权限,执行到此命令时,就会卡主
方法01
1 | cmd := exec.Command("/bin/bash","-c","echo XXpasswordYY|sudo -S cat /etc/shadow") |
sudo指令有一个-S参数,这个参数表示sudo将从stdin接收密码,我们可以利用-S参数和Linux的pipe特性,来实现自动输入密码。
1 | $ echo 'password' | sudo -S command |
不是所有的程序都有类似于-S这样的参数。
自动输入密码有的时候很有用,比如你的cron里面的任务,很可能就需要这样的机制,但是也带来了安全方面的风险,需自行评估。
有些程序在于用户交互时,不能通过stdin接收交互信息,只能通过terminal device来接收,需要注意这个细节。
方法02
参考:go的ssh怎么执行sudo:https://golangtc.com/t/5397ef11320b5253b5000011
一个思路。主要就是连接一个ssh interactive shell ,然后连接stdin, stdout, stderr ,然后根据输出相应地处理就好了
方法03:gexpect
ThomasRooney/gexpect:https://github.com/ThomasRooney/gexpect/blob/master/examples/ftp.go
1 | child, err := gexpect.Spawn("ftp ftp.openbsd.org") |
方法04:其他不好使方法
貌似好使,实际不行的
Go 调用交互式shell:https://www.jianshu.com/p/9a1cbce39c3d
1 | buffer := bytes.Buffer{} |
如何在给定sudo密码的情况下使用Golang to shell命令:https://cloud.tencent.com/developer/ask/789868
1 | cmd := exec.Command("sudo", "-S", "--", "cat", "/etc/shadow") |
在golang中输入命令的密码:https://www.5axxw.com/questions/content/5lsq1u
其他方式
特定命令免密码
echo ‘password’ | sudo -kS ls解决方案有效,但它有一些安全方面的缺点,其中大部分已在terdon的回答评论中提到过。因此,我想提出一个不同的方法:
如果它只是您经常需要执行的一个命令,例如apt-get upgrade,您可以配置您的系统,使sudo someCommand不需要密码。
为此,请运行visudo并输入类似于以下内容的内容:
1 | myusername ALL=(ALL) NOPASSWD: /usr/bin/apt-get upgrade |
请注意,如果输入不带参数的命令(例如,在此示例中没有upgrade),则允许用户使用任何参数运行它,因此请小心使用。
增加超时,而不是完全删除密码,因此您只需每天输入几次;在终端中,运行:
1 | sudo visudo |
在文件末尾,添加以下行以设置超时30分钟(用您的用户名替换jsmith)。
1 | Defaults:jsmith timestamp_timeout=30 |
你可以使用你想要的任何数字; -1表示没有超时(仅在第一次提示时),而0表示即时超时(每次sudo时都会提示)。默认超时为5分钟。
最终选择:gexcept
需要注意的是:gexcept只能执行单个命令,不能通过”;,&&,||”等串联多个命令。建议每个命令循环即可
参考
sudo时,自动输入密码:https://www.maixj.net/ict/sudo-zidong-mima-21899
go的ssh怎么执行sudo:https://golangtc.com/t/5397ef11320b5253b5000011
GoLang执行需要输入密码的命令:t.zoukankan.com/mrylong-p-10763428.html
如何避免被sudo提示输入密码?:https://ubuntuqa.com/article/1342.html