You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP通过SSH调用bash脚本时sudo命令无法执行的权限排查

这个问题我之前帮同事排查过,核心原因就是远程执行sudo的时候没法交互式输入密码,而且默认sudo配置要求验证身份,所以script2.sh里的systemctl命令才没跑起来。给你几个靠谱的解决办法,按安全优先级排序:

解决办法

1. 配置目标服务器的sudo免密(最推荐,安全可控)

这是最稳妥的方案,只给特定用户、特定命令开放免密sudo权限,避免过度授权带来的风险:

  • 登录到目标服务器(10.10.10.10),用有sudo权限的账号执行visudo(一定要用visudo编辑,它会自动检查语法,避免写错导致sudo失效)
  • 在文件末尾添加一行,替换成你的实际信息:
    user ALL=(ALL) NOPASSWD: /usr/bin/systemctl start service
    
    解释一下:
    • user是你SSH登录目标服务器的用户名
    • /usr/bin/systemctl start service是要执行的完整命令(可以用which systemctl查到systemctl的绝对路径)
    • 如果需要授权多个命令,用逗号分隔即可,比如:/usr/bin/systemctl start service, /usr/bin/systemctl stop service
  • 保存退出后,先在本地测试一下:执行ssh user@10.10.10.10 sudo /usr/bin/systemctl start service,确认不需要输入密码就能执行成功

2. 给SSH命令分配伪终端(解决无终端导致的sudo失败)

有些情况下,sudo需要终端环境才能触发验证流程,而远程SSH默认是非交互式无终端的,这时候可以加-t参数强制分配伪终端:
修改script.sh里的ssh命令为:

ssh -t user@10.10.10.10 path-to-script/script2.sh

如果一次-t不够,还可以用-tt强制分配(双重强制),不过这个方案最好配合免密sudo一起用,不然还是会卡在密码输入环节。

3. 用expect自动输入sudo密码(不推荐,安全性低)

如果实在没法配置免密sudo,可以用expect脚本自动输入密码,但这个方案的风险很高——密码会明文存储在脚本里,很容易泄露。如果是测试环境可以临时用:
把script.sh里的原ssh命令替换成:

expect << EOF
spawn ssh user@10.10.10.10 path-to-script/script2.sh
expect "password:"
send "你的sudo密码\r"
expect eof
EOF

注意:目标服务器需要先安装expect工具(比如用apt install expect或yum install expect)。

4. 检查script2.sh的权限和命令路径

还有两个小细节容易被忽略:

  • 确保script2.sh有可执行权限:在目标服务器上执行chmod +x path-to-script/script2.sh
  • 在script2.sh里使用命令的绝对路径,比如写成/usr/bin/sudo /usr/bin/systemctl start service,避免远程环境的PATH变量不全导致找不到命令

内容的提问来源于stack exchange,提问作者SameAs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:09:28