如何以不同用户身份在远程服务器上执行命令

如何以不同用户身份在远程服务器上执行命令

我正在尝试使用 ssh 从服务器 A 连接到服务器 B 并使用其他用户执行命令。但是,当我尝试在日志文件中搜索模式时,它显示“无法打开日志文件”,下面是示例代码

ssh  -t user@hostname <<EOF
sudo su - someotheruser
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ $a -eq 0 ] 
then
echo "Success"
else
echo "Failure"
fi 
EOF

一旦我运行脚本,它就会说:unable to open "tail........."

我无法在服务器 B 上保持登录状态并运行多个命令。

答案1

仔细考虑每个命令的执行时间、运行位置以及接收的输入。

  1. 首先扩展此处的文档。这意味着tail/awk管道是在本地主机上执行的,变量替换$a也是如此。
  2. 然后ssh执行命令。它接收此处扩展的文档;这些是在远程 shell 中执行的命令。
  3. 远程 shell 执行时不带参数,因此它从标准输入读取要执行的命令。这些命令包括sudo,但也可能(取决于 shell)以下一些行。
  4. 远程 shell 执行sudo su - someotheruser.这会运行一个 shell,someotheruser它首先读取并执行该用户的.profile,然后从其标准输入读取命令。标准输入包含第一个远程 shell 未读取的内容,这在某种程度上是不可预测的(这取决于 shell 以及它从输入管道读取了多少内容)。
  5. 运行的 shellsomeotheruser运行它读取的命令(如果有)。
  6. 运行的 shellsomeuser执行该if命令(如果它已读取)。

为了避免此处的文档扩展,请在heredoc标记周围使用引号。为了避免标准输入的不正当混合,请使用sh -c …或明确第二个远程 shell 接收的输入内容。

ssh  -t user@hostname <<'SSH_EOF'
sudo su - someotheruser <<'SU_EOF'
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ] 
then
echo "Success"
else
echo "Failure"
fi
SU_EOF
SSH_EOF

你真的需要源码someotheruser.profile?如果没有,请使用sudo -u someotheruser.如果这样做,请使用sudo -i -u someotheruser.相应地调整您的 sudoers 规则。

读取日志文件是唯一需要提升权限的事情,因此tail仅以someotheruser.

ssh -t user@hostname <<'SSH_EOF'
a=`sudo -u someotheruser tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ] 
then
echo "Success"
else
echo "Failure"
fi
SSH_EOF

如果您不混合使用特权升级方法,您的生活将会变得更加轻松。不要使用sudo从 切换someuser到,而是someotheruser使用 SSH 到 localhost。链接两个 ssh 命令很容易。设置一个密钥 - 您甚至可以设置一个仅允许运行特定命令的密钥,例如tail -10 /somepath/application.log..ssh/config通过帐户定义 SSH 的别名someuser

Host hostname-someotheruser
HostName hostname
UserName someotheruser
ProxyCommand ssh someuser@hostname

然后运行

a=$(ssh hostname-someotheruser tail -10 /somepath/application.log |
    awk '/Agent Exited/ { print $3 }')
if [ "$a" -eq 0 ] 
then
  echo "Success"
else
  echo "Failure"
fi

答案2

If 语句不是命令,需要由 shell 解释。你可以试试这个。创建本地脚本

a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
[ $a -eq 0 ] && echo "Success" || echo "Faiilure"

并调用 bash shell 来执行这些命令

ssh  -t user@hostname 'echo "pass" | sudo -Sv && bash -s' < script.sh

答案3

从你的描述来看,我认为有两个问题。首先,你不需要那个<。根据手册页ssh,主机名后面的字符串将立即被识别为远程执行的命令。要执行多个命令,您可以将它们全部放入单个带引号的字符串中。该字符串将被发送到远程并像脚本一样执行。

ssh -t user@hostname 'tail -10 /somepath/application.log | awk \'/Agent Exited/ { print $3 }\'; if [ $a -eq 0 ]; then echo "Success"; else echo "Failure"; fi'

相关内容