我正在尝试使用 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
仔细考虑每个命令的执行时间、运行位置以及接收的输入。
- 首先扩展此处的文档。这意味着
tail
/awk
管道是在本地主机上执行的,变量替换$a
也是如此。 - 然后
ssh
执行命令。它接收此处扩展的文档;这些是在远程 shell 中执行的命令。 - 远程 shell 执行时不带参数,因此它从标准输入读取要执行的命令。这些命令包括
sudo
,但也可能(取决于 shell)以下一些行。 - 远程 shell 执行
sudo su - someotheruser
.这会运行一个 shell,someotheruser
它首先读取并执行该用户的.profile
,然后从其标准输入读取命令。标准输入包含第一个远程 shell 未读取的内容,这在某种程度上是不可预测的(这取决于 shell 以及它从输入管道读取了多少内容)。 - 运行的 shell
someotheruser
运行它读取的命令(如果有)。 - 运行的 shell
someuser
执行该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'