我有一个shell脚本如下
#!/bin/bash
USER=someuser
HOSTNAMEORIP=somehostname
SCRIPT="/etc/rc.d/netif restart && /etc/rc.d/routing restart"
su -c "ssh -l ${USER} ${HOSTNAMEORIP} ${SCRIPT}" -s /bin/sh someotheruser
如果我登录到机器并运行 "/etc/rc.d/netif restart && /etc/rc.d/routing restart"
有用。但是如果我运行上面的整个脚本,我会得到 sh: 1: /etc/rc.d/routing: not found
就好像它没有处理脚本部分一样。我什至可以在没有像这样的用户的情况下使用上面的脚本
#!/bin/bash
USER=someuser
HOSTNAMEORIP=somehostname
SCRIPT="/etc/rc.d/netif restart && /etc/rc.d/routing restart"
ssh -l ${USER} ${HOSTNAMEORIP} ${SCRIPT}
它有效,但我需要使用 su -c <command> -s /bin/sh user
因为另一个应用程序正在调用该脚本,并且关联的用户是唯一一个使用 ssh key 登录/没有密码到另一台机器的用户。
我怎样才能制作su -c "ssh -l ${USER} ${HOSTNAMEORIP} ${SCRIPT}" -s /bin/sh someotheruser
在此用例中正确运行脚本?
最佳答案
让我们来完成它。这个命令:
su -c "ssh -l ${USER} ${HOSTNAMEORIP} ${SCRIPT}" -s /bin/sh someotheruser
将此字符串作为 shell 命令执行:
ssh -l someuser somehostname /etc/rc.d/netif restart && /etc/rc.d/routing restart
这显然是错误的,并且会因同样的错误而失败。
要修复它,让我们修复命令并向后工作。你应该执行
ssh -l someuser somehostname '/etc/rc.d/netif restart && /etc/rc.d/routing restart'
因此,您可以像这样更新您的脚本:
#!/bin/bash
USER=someuser
HOSTNAMEORIP=somehostname
SCRIPT="/etc/rc.d/netif restart && /etc/rc.d/routing restart"
su -c "ssh -l ${USER} ${HOSTNAMEORIP} '${SCRIPT}'" -s /bin/sh someotheruser
# ^--- ^---
请注意,这取决于 $SCRIPT
不包含嵌入式单引号这一事实。如果知道或不知道,则可以在嵌入字符串中使用 $(printf "%q""$SCRIPT")
而不是 '$SCRIPT'
让 bash 自动转义它。
或者您可以切换到 sudo
。由于它使用安全可靠的 execve(2)
语义而不是 system(3)
语义,因此您不必嵌套转义:
sudo -u someotheruser ssh -l "$USER" "$HOSTNAMEORIP" "$SCRIPT"
关于linux - 从脚本运行时,Bash 脚本无法正确执行命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45119911/