Значения переменных в удаленно выполняемых сложных командах bash - PullRequest
0 голосов
/ 29 мая 2019

Я хочу запустить сложный список команд на удаленном хосте. Я мог бы легко решить, создав другой сценарий с такими командами, а затем попросить другой сценарий вызвать его (с копированием на удаленный хост или без него), но я не хочу. Моя проблема в том, что у меня есть некоторые переменные, которые фиксируются для всего скрипта, а затем у меня есть переменная цикла for. Я могу заставить один из двух быть правильно оценен на удаленном хосте, но ни того, ни другого. Все, что я нашел по схожим вопросам, это разговоры об использовании кавычек заметок "или" вокруг разных элементов. Ничто из того, что я пробовал, не работало как с фиксированными (для расширения до ssh), так и с переменными цикла (для расширения). удаленно) в то же время (выделите, @Inian, поскольку вы не можете, блядь, прочитать полный вопрос, прежде чем пометить его как дубликат того, что не является дубликатом).

fixed_value="blue"

ssh remote_host << "EOF"
    value_list="VALUE1 VALUE2"
    for i in $value_list; do
        echo "executing $i"
        my_program -arg1 $i -arg2 "$fixed_value"
    done
EOF

Я ожидаю запустить my_program (двоичный файл на удаленном хосте) с двумя аргументами, один из которых является фиксированным и фактически передается в качестве входных данных в локальный скрипт, другой читается из списка фиксированных значений, так что в этом примере я должен выполнить на удаленном хосте следующее:

my_program -arg1 VALUE1 -arg2 blue
my_program -arg1 VALUE2 -arg2 blue

Мне, вероятно, нужен способ «передать значения» сценарию, выполняемому на удаленном хосте, или принудительное вычисление $ fixed_value перед отправкой команды (что я пытался сделать с помощью кавычек, но это не сработало ), не мешая оценке $ i на удаленном хосте. Потому что все, что я получаю, переключая кавычки (или удаляя их, или меняя их), это либо:

my_program -arg1 -arg2 blue
my_program -arg1 -arg2 blue

или

my_program -arg1 VALUE1 -arg2
my_program -arg1 VALUE2 -arg2

Ответы [ 2 ]

1 голос
/ 29 мая 2019
#!/bin/bash

fixed_value="blue"
qq='"'

ssh remote_host bash -c "
  value_list='VALUE1 VALUE2'
  for i in \$value_list; do
    echo ${qq}executing \$i$qq
    my_program -arg1 \$i -arg2 '$fixed_value'
  done
"

Я обернул команду в команду bash -c "…".Поскольку вам все еще нужны двойные кавычки и поскольку я пришел к недоверию к экранированным кавычкам, я создал переменную $qq для представления символа двойной кавычки.Переменные, передаваемые со стороны сервера ($qq и $fixed_value), не экранируются, поэтому их значения передаются на сервер.Переменные для оценки на стороне сервера ($value_list и $i) экранируются, поэтому они интерпретируются удаленным вызовом bash.

Код выхода этого сценария на стороне клиента будет кодом выхода из ssh, который должен быть продиктован кодом выхода из последней итерации my_program (если только ssh сам не завершится с ошибкой или завершится).

1 голос
/ 29 мая 2019

Реорганизованного:

fixed_value="blue"
value_list=( VALUE1 VALUE2 )
for i in "${value_list[@]}"; do
    echo "executing $i"
    ssh remote_host "my_program -arg1 $i -arg2 $fixed_value"
done

Если вы действительно хотите, чтобы все это было сделано за один вызов, запишите его в виде сценария, scp over, затем ssh, чтобы вызвать его на целевом компьютере.

... или записать его локально во временный файл:

$: cat a
echo '
fixed_value="blue"
value_list=( VALUE1 VALUE2 )
for i in "${value_list[@]}"; do
    echo "executing $i"
    echo "my_program -arg1 $i -arg2 $fixed_value"
done
'>/tmp/foo && . /tmp/foo && rm /tmp/foo

и затем запустите его как

ssh remote_host < a

, который производит:

Pseudo-terminal will not be allocated because stdin is not a terminal.
executing VALUE1
my_program -arg1 VALUE1 -arg2 blue
executing VALUE2
my_program -arg1 VALUE2 -arg2 blue
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...