Предотвращение преждевременного расширения параметров оболочки в связанных командах - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть система, которая позволяет выполнять команды с хоста на различные внешние машины, от сценария оболочки bash, используя ssh или 'sersh', который похож на ssh, но отправляет команды через последовательный порт.(Детали этих команд не имеют значения.)

Я пытаюсь объединить команды в одну цепочку - от одной внешней машины до третьей.Мне трудно понять, как заставить оболочку расширять параметры только на конечном компьютере.

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 голосов
/ 13 февраля 2019

[@ MadPhysicist напоминает мне, что мне все равно придется избегать расширений переменных.Мой ответ оставлен здесь для справки, но @MadPhysicist прав: мой ответ, вероятно, не отвечает на заданный вопрос.]

Используйте eval.

Попробуйте выполнить это упражнение, набрав следующие четыреКоманды в командной строке вашей оболочки.Я полагаю, что упражнение, вероятно, ответит на ваш вопрос.

$ X=55
$ A='echo $(( $X + $X ))'
$ echo "$A"
$ eval "$A"

Как только упражнение покажет вам, что делает встроенная команда оболочки eval, вы можете получить желаемый эффект, используя eval на последнем автомате в вашей цепочке.

[Обратите внимание, что в упражнении написано: A='echo $(( $X + $X ))'.Это не говорит, A=`echo $(( $X + $X ))`.Обратите внимание, как кавычки наклоняются.Здесь вам нужны обычные одинарные кавычки, а не обратные кавычки.]

...