首页 > 解决方案 > 用于远程执行 SSH 命令的 Bash 脚本函数包装器

问题描述

我正在尝试创建一个允许我远程执行命令的 SSH Bash 包装函数。目标是拥有传递给函数的函数名和参数,而不用担心如何转义引用。第二个目标(虽然不那么重要)是捕获执行命令的结果。

我尝试了各种方法,但似乎没有一个在函数中起作用。

这里有两种不同的方法,我觉得我最接近预期的结果:

#!/bin/bash
s="srvr01"
ss="srvr02"

# Run commands on primary
function ssh1() {
  printf -v var "%s" "$*"
  ssh root@$s <<END
  x() {
    $*
  }
  x "$var"
END
}

# Run commands using secondary method
function ssh2() {
  printf -v var_str "%s" "$*"
  ssh -T -p 22 root@$ss $var_str
}

sshb() {
  ssh1 $*
  ssh2 $*
}

ssh1 echo 'net.ipv4.ip_nonlocal_bind=1' >> /etc/sysctl.conf
ssh2 echo 'net.ipv4.ip_nonlocal_bind=1' >> /etc/sysctl.conf

通过将函数传递给 ssh 然后调用它,我希望命令以安全转义的方式执行,而不是获取:
第 27 行:/etc/sysctl.conf: Permission denied
第 28 行:/etc/sysctl.conf : 没有权限

标签: bashssh

解决方案


您需要引用输出重定向运算符,否则它们将由您的本地 shell 处理,而不是作为参数传递给函数。

ssh1 echo 'net.ipv4.ip_nonlocal_bind=1' '>>' /etc/sysctl.conf
ssh2 echo 'net.ipv4.ip_nonlocal_bind=1' '>>' /etc/sysctl.conf

您还需要evalx()函数中使用,因为扩展变量后不会处理重定向运算符。并且您需要转义$应该在远程系统上扩展的 in 变量。

function ssh1() {
  printf -v var "%s" "$*"
  ssh root@$s <<END
  x() {
    eval "\$1"
  }
  x "$var"
END
}

我不确定那是什么意思printf,你可以做得到var="$*"相同的结果。你甚至不需要var变量,只需使用x "$*"实际上,我想我会写成:

function ssh1() {
    ssh root@$s <<END
$*
END
}

推荐阅读