我有一个系统,该系统允许使用ssh或'sersh'从bash shell脚本从主机向各种外部计算机执行命令,这与ssh类似,但通过串行端口发送命令。 (这些命令的详细信息无关紧要。)
我正在尝试将命令链接在一起,从一台外部计算机到 第三台机器。我很难弄清楚如何让Shell仅在最终机器上扩展参数。
function do_cmd () {
case $TRANSPORT in
ssh)
ssh -i ${SSH_KEY} ${LOGIN}@${IPADDR} "$@"
;;
serial)
sersh ${SER_LOGIN}@{SERIAL_DEV} "$@"
;;
ssh2serial)
ssh -i ${SSH_KEY} ${LOGIN}@{IPADDR} \
"sersh ${SER_LOGIN}@${SERIAL_DEV} $@"
;;
*)
echo "Unknown transport $TRANSPORT"
;;
esac
}
do_cmd "echo hello"
do_cmd "echo \"my pid is \$\$\""
do_cmd "cd /proc ; for pid in 1* ; do echo \$pid, ; done"
当TRANSPORT为'ssh'或'serial'时,所有这三个调用均正常工作。对于TRANSPORT'ssh2serial',在对do_cmd的第二次调用中,$$会过早展开(在中间计算机上,而不是在最终计算机上)。第三次调用do_cmd时,$ pid结束 在循环执行之前将其扩展为空字符串 最终机器。
我考虑过将美元符号转义两次,但是 调用者不知道有多少级中间计算机。 有没有办法防止中间参数扩展 机器,并且只能在最终机器上使用?
答案 0 :(得分:0)
[@ MadPhysicist提醒我,我仍然必须逃避变量扩展。我的答案留在下面供参考,但@MadPhysicist是正确的:我的答案可能无法回答所提出的问题。]
使用eval
。
尝试此练习,在shell的命令行中键入以下四个命令。我相信该练习可能会回答您的问题。
$ X=55
$ A='echo $(( $X + $X ))'
$ echo "$A"
$ eval "$A"
一旦练习向您显示了Shell的内置命令eval
的功能,您就可以在链中的最后一台计算机上使用eval
来获得想要的效果。
[请注意,练习显示A='echo $(( $X + $X ))'
。它没有说A=`echo $(( $X + $X ))`
。观察引号倾斜的方式。您想在这里使用普通的单引号,而不是反引号。]