如何使用 sudo 通过 ssh 运行任意复杂的命令?

如何使用 sudo 通过 ssh 运行任意复杂的命令?

我有一个只能以我的用户名 (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目录,其中包含空格)。

是否有一个通用的解决方案允许我传递任何命令,无论引用有多复杂/疯狂,或者这是我达到的某种限制?还有其他可能的、可能更易读的解决方案吗?

答案1

我有时使用的技巧是使用 base64 对命令进行编码,然后将其通过管道传输到另一个站点上的 bash:

MYCOMMAND=$(base64 -w0 script.sh)
ssh user@remotehost "echo $MYCOMMAND | base64 -d | sudo bash"

这将对脚本进行编码,将逗号、反斜杠、引号和变量放在安全字符串内,并将其发送到另一台服务器。(-w0需要禁用换行,默认情况下换行发生在第 76 列)。另一方面,$(base64 -d)将解码脚本并将其提供给 bash 执行。

无论脚本有多复杂,我从来没有遇到过任何问题。解决了转义问题,因为您不需要转义任何内容。它不会在远程主机上创建文件,您可以轻松运行非常复杂的脚本。

答案2

看到-tt选项了吗?阅读ssh(1)手册。

ssh -tt root@host << EOF
sudo some # sudo shouldn't ask for a password, otherwise, this fails. 
lines
of
code 
but be careful with \$variables
and \$(other) \`stuff\`
exit # <- Important. 
EOF

我经常做的一件事就是使用 vim 并使用:!cat % | ssh -tt somemachine技巧。

答案3

我认为最简单的解决方案在于修改@thanasisk 的评论。

创建一个脚本,scp将其发送到机器,然后运行它。

将脚本rm本身放在开头。shell 已打开该文件,因此已加载该文件,然后可以毫无问题地将其删除。

通过按此顺序执行操作(rm首先,其次是其他内容),它甚至会在某个时候失败时被删除。

答案4

更新:示例现在明确使用sudo

以下是使用 Bash 语法和复合赋值通过 SSH 使用 sudo 执行任意复杂命令的方法:

CMD=$( cat <<'EOT'
echo "Variables like '${HOSTNAME}' and commands like $( whoami )"
echo "will be interpolated on the server, thanks to the single quotes"
echo "around 'EOT' above."
EOT
) \
SSHCMD=$(
  printf 'ssh -tq myuser@hostname sudo -u scriptuser bash -c %q' "${CMD}" ) \
bash -c '${SSHCMD}'

CMD=$( cat <<EOT
echo "If you want '${HOSTNAME}' and $( whoami ) to be interpolated"
echo "on the client instead, omit the the single quotes around EOT."
EOT
) \
SSHCMD=$(
  printf 'ssh -tq myuser@hostname sudo -u scriptuser bash -c %q' "${CMD}" ) \
bash -c '${SSHCMD}'

正确格式化命令以便在其他地方动态执行(例如嵌套 shell、远程 SSH shell 等)可能非常棘手 - 请参阅https://stackoverflow.com/a/53197638/111948以更好地解释原因。复杂的 bash 结构(如上述语法)可以帮助这些命令正常工作。

有关如何cat以及<<结合以形成内联的更多信息这里的文件, 请参见https://stackoverflow.com/a/21761956/111948

相关内容