当需要重新启动时,我尝试通过脚本重新启动一些 Ubuntu 服务器。
当我将测试作为非交互式命令执行 bash 时,我得到的结果是不需要重新启动,即使文件/var/run/reboot-required存在。
usera@client:~$ ssh server02 bash -c 'test -f /var/run/reboot-required && echo sudo reboot || echo "$(hostname): no reboot required"'
server02: no reboot required
Run Code Online (Sandbox Code Playgroud)
当我通过 SSH 登录到同一服务器并手动运行测试时,我得到了正确的结果sudo reboot。
usera@client:~$ ssh server02
Last login: Tue Jun 14 08:03:00 2022 from 146.140.16.1
usera@server02:~$ test -f /var/run/reboot-required && echo sudo reboot || echo "$(hostname): no reboot required"
sudo reboot
usera@server02:~$ bash -c 'test -f /var/run/reboot-required && echo sudo reboot || echo "$(hostname): no reboot required"'
sudo reboot
Run Code Online (Sandbox Code Playgroud)
我需要改变什么才能得到正确的结果?
我很确定这是因为 SSH 将命令行传递到远程端的方式,它通过连接它获得的所有参数、用空格将它们连接起来并让远程上的 shell 解析并执行该参数来实现这一点。
\n考虑一下,它的ssh somehost ls -l /etc/passwd工作方式与 相同ssh somehost \'ls -l /etc/passwd\',后者不会给出关于不存在的奇怪命名命令的错误,这与直接\'ls -l /etc/passwd\'在 shell 命令行上运行不同。
所以,
\nssh somehost bash -c \'test whatever ||\xc2\xa0echo no\'\nRun Code Online (Sandbox Code Playgroud)\n变成命令行
\nbash -c test whatever ||\xc2\xa0echo no\nRun Code Online (Sandbox Code Playgroud)\nBash 开始运行命令test,$0设置为whatever。test没有参数失败,所以|| echo运行。您也可以尝试类似的操作,它应该只在您的远程主目录中ssh somehost bash -c \'ls -l /etc/passwd\'运行。ls
因此,尝试不使用中间 shell:
\nssh server02 \'test -f /etc/passwd && echo passwd exists || echo "$(hostname): passwd does not exist"\'\nRun Code Online (Sandbox Code Playgroud)\n或者你可以做类似的事情
\nssh server02 \'bash -c "test -f /etc/passwd && echo yes ||\xc2\xa0echo \\"\\$(hostname): no\\"\'\nRun Code Online (Sandbox Code Playgroud)\n但是如果您想嵌套另一个带引号的字符串并确保它是运行您拥有的任何扩展的最内层外壳,那么那里的引号确实会变得很棘手。这并不重要,$(hostname)因为它会从远程的任一 shell 给出相同的结果,但在更一般的情况下,引用地狱就在那里。在这样的复杂情况下,在远程创建一个文件并从那里运行脚本会容易得多。
这基本上与带引号的 ssh 命令中的问题相同。
\n另请参阅通过 SSH 执行 `sh -c` 脚本(安全且明智地传递参数),了解传递复杂命令的其他解决方案,以及如何在不知道远程用户的登录 shell 的情况下通过 ssh 执行任意简单命令?对于涉及可能未知的远程登录 shell 的罕见情况。
\n| 归档时间: |
|
| 查看次数: |
330 次 |
| 最近记录: |