是否可以每次都将 ssh 连接存储在 bash 脚本中而不是 $(ssh user@ip command) 中?

Pat*_*ryk 4 bash ssh shell-script

我认为我已经拥有的代码效率不高,因为它每次都必须连接到同一台机器并执行命令。代码:

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)
Run Code Online (Sandbox Code Playgroud)

$COMMAND在大多数情况下,哪里是某种grep.

我可以以某种方式存储 ssh 连接或重构代码,这样它就不会每次都连接到机器吗?

Sté*_*las 5

如果远程用户的 shell 是 ksh93、zsh 或 bash(或sh作为其中任何一个实现),您可以执行以下操作:

eval "$(ssh -nq "$user@$host" '
  printf "%s=%q\n" \
    tmp1 "$(command1)" \
    tmp2 "$(command2)" \
    tmp3 "$(command3)"')"
Run Code Online (Sandbox Code Playgroud)

但是请注意,您将丢失远程命令的退出状态。这可能允许远程用户使您执行任意命令(例如,通过在他们的 中输出某些内容~/.bashrc)。

另一种选择是使用 的ControlMaster功能ssh在多个 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)
Run Code Online (Sandbox Code Playgroud)

(和tmp2...相同)。如果存在,则该语法重新使用现有连接,否则创建新连接。它将在空闲 5 分钟后终止,或者您可以使用以下命令明确关闭它:

ssh -o ControlPath="$HOME/.ssh/ctl/%L-%r@%h:%p" -O exit "$user@$host"
Run Code Online (Sandbox Code Playgroud)

第一次调用需要时间,因为它将执行连接和身份验证,而接下来的调用会快很多。

当然,如果您不需要将三个命令输出放入三个不同的变量中,您可以执行以下操作:

tmp=$(ssh -nq "$user@$host" '
   cmd1
   cmd2
   cmd3')
Run Code Online (Sandbox Code Playgroud)

因此 3 个命令输出将出现在$tmp.