我正在尝试创建一个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:权限被拒绝
第28行:/etc/sysctl.conf:权限被拒绝
答案 0 :(得分:1)
您需要引用输出重定向运算符,否则它们将由您的本地shell处理,而不是作为参数传递给函数。
ssh1 echo 'net.ipv4.ip_nonlocal_bind=1' '>>' /etc/sysctl.conf
ssh2 echo 'net.ipv4.ip_nonlocal_bind=1' '>>' /etc/sysctl.conf
您还需要在eval
函数中使用x()
,因为扩展变量后不会处理重定向运算符。并且您需要转义$
变量,这些变量应该在远程系统上扩展。
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
}