我有一个只能以我的用户名 (myuser) 登录的系统,但我需要以其他用户 (scriptuser) 的身份运行命令。到目前为止,我已经想出了以下内容来运行我需要的命令:
ssh -tq myuser@hostname "sudo -u scriptuser bash -c \"ls -al\""
但是,如果当我尝试运行更复杂的命令时,例如[[ -d "/tmp/Some directory" ]] && rm -rf "/tmp/Some directory"
我很快就会遇到引用问题。我不确定如何将这个示例复杂命令传递给bash -c
,当\"
已经划定了我正在传递的命令的边界时(所以我不知道如何引用 /tmp/Some 目录,其中包含一个空格。
是否有一个通用的解决方案允许我通过任何命令,无论引用多么复杂/疯狂,或者这是我已经达到的某种限制?还有其他可能的,也许更易读的解决方案吗?
我有时使用的一个技巧是使用 base64 对命令进行编码,并将其通过管道传输到另一个站点上的 bash:
这将使用安全字符串中的任何逗号、反斜杠、引号和变量对脚本进行编码,并将其发送到其他服务器。(
-w0
需要禁用换行,默认情况下发生在第 76 列)。另一方面,$(base64 -d)
将解码脚本并将其提供给 bash 以执行。无论脚本多么复杂,我都没有遇到任何问题。解决了转义的问题,因为你不需要转义任何东西。它不会在远程主机上创建文件,您可以轻松运行极其复杂的脚本。
看到
-tt
选项了吗?阅读ssh(1)
手册。我经常做的一件事是使用 vim 并使用
:!cat % | ssh -tt somemachine
技巧。我认为最简单的解决方案在于修改@thanasisk 的评论。
创建一个脚本,
scp
将它放到机器上,然后运行它。在开始时拥有脚本
rm
本身。shell 已经打开了文件,所以它已经被加载,然后可以毫无问题地删除。通过按此顺序执行操作(
rm
首先是其他内容),它甚至会在某些时候失败时被删除。您可以使用
%q
格式说明符 withprintf
为您处理变量转义:printf -v
将输出写入变量(在本例中为$cmd_str
)。我认为这是最简单的方法。无需传输任何文件或对命令字符串进行编码(尽管我喜欢这个技巧)。这是一个更复杂的示例,表明它也适用于方括号和与号之类的东西:
我没有测试过它,
sudo
但它应该很简单:如果需要,您可以跳过一个步骤并避免创建中间变量:
甚至完全避免创建变量:
更新:示例现在明确使用
sudo
.这是一种使用带有复合赋值的 Bash 语法通过 sudo 通过 SSH 执行任意复杂命令的方法:
正确格式化命令以在其他地方动态执行(例如嵌套 shell、远程 SSH shell 等)可能非常棘手 - 请参阅https://stackoverflow.com/a/53197638/111948以了解原因。复杂的 bash 结构,如上面的语法,可以帮助这些命令正常工作。
有关如何
cat
和<<
组合形成内联此处文档的更多信息,请参阅https://stackoverflow.com/a/21761956/111948您是否知道可以使用
sudo
为您提供一个 shell,您可以在其中以所选用户身份运行命令?您可以在本地计算机上定义脚本,然后
cat
将其通过管道传输到远程计算机:简单易行。
如果您使用足够现代的 Bash shell,您可以将您的命令放在一个函数中,并使用
export -p -f function_name
. 然后,该字符串的结果可以包含不必以 root 身份运行的任意命令。使用我在 Unix.SE 上的回答中的管道的示例:
检索保存登录用户的文件并在根目录下安装程序的示例:
如果您想使用 运行整个命令
sudo
,可以使用以下命令:这是我的(未经真正测试的)糟糕的解决方案:
不是你可以这样做:
下一步是创建一个
betterssh
已经执行此操作的脚本: