防止链式命令中过早的Shell参数扩展

时间:2019-02-12 20:25:56

标签: bash parameters expansion

我有一个系统,该系统允许使用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结束 在循环执行之前将其扩展为空字符串 最终机器。

我考虑过将美元符号转义两次,但是 调用者不知道有多少级中间计算机。 有没有办法防止中间参数扩展 机器,并且只能在最终机器上使用?

1 个答案:

答案 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 ))`。观察引号倾斜的方式。您想在这里使用普通的单引号,而不是反引号。]