我认为我已有的代码效率不是很高,因为它每次都必须连接到同一台机器并执行命令。代码:
tmp=$(ssh -nq $USER@$IP "$COMMAND" 2>> $LOG)
tmp1=$(ssh -nq $USER@$IP "$COMMAND1" 2>> $LOG)
tmp2=$(ssh -nq $USER@$IP "$COMMAND2" 2>> $LOG)
tmp3=$(ssh -nq $USER@$IP "$COMMAND3" 2>> $LOG)
在大多数情况下$COMMAND
,是某种grep
.
我可以以某种方式存储 ssh 连接或重构代码,这样它就不会每次都连接到机器吗?
答案1
如果远程用户的 shell 是 ksh93、zsh 或 bash(或sh
实现为其中任何一个),您可以执行以下操作:
eval "$(ssh -nq "$user@$host" '
printf "%s=%q\n" \
tmp1 "$(command1)" \
tmp2 "$(command2)" \
tmp3 "$(command3)"')"
但请注意,您将丢失远程命令的退出状态。这可能允许远程用户导致您执行任意命令(例如通过在他们的 中输出某些内容~/.bashrc
)。
另一种选择是使用ssh 的多个调用之间共享连接ControlMaster
的功能。ssh
您也可以使用该auto
模式。就像是:
mkdir -p -- ~/.ssh/ctl
tmp1=$(ssh -o ControlMaster=auto \
-o ControlPath="$HOME/.ssh/ctl/%L-%r@%h:%p" \
-o ControlPersist=5m -nq "$user@$host" cmd1)
(对于...也一样tmp2
)。该语法将重新使用现有连接(如果存在),否则创建一个新连接。它将在闲置 5 分钟后终止,或者您可以使用以下命令显式关闭它:
ssh -o ControlPath="$HOME/.ssh/ctl/%L-%r@%h:%p" -O exit "$user@$host"
第一次调用将花费一些时间,因为它将执行连接和身份验证,而接下来的调用会快得多。
当然,如果您不需要将三个命令输出放入三个不同的变量中,您可以这样做:
tmp=$(ssh -nq "$user@$host" '
cmd1
cmd2
cmd3')
因此 3 个命令输出将串联显示在$tmp
.
答案2
您可以使用此处文档:
cat <<EOF | ssh $USER@$IP 2>>$LOG
grep x *
grep -i y *.log
EOF