Как установить и расширить переменные в разделе heredoc
У меня есть heredoc, который должен вызывать существующие переменные из основного скрипта и устанавливать свои собственные переменные для использования позже. Что-то вроде этого:
count=0
ssh $other_host <<ENDSSH
if [[ "${count}" == "0" ]]; then
output="string1"
else
output="string2"
fi
echo output
ENDSSH
Это не работает, потому что "output" не установлен ни к чему.
Я попытался использовать решение из этого вопроса:
count=0
ssh $other_host << \ENDSSH
if [[ "${count}" == "0" ]]; then
output="string1"
else
output="string2"
fi
echo output
ENDSSH
Это тоже не сработало. $output установлен в "string2", потому что $ count не было расширено.
Как я могу использовать heredoc, который расширяет переменные из родительского скрипта и устанавливает свои собственные переменные?
3 ответа
Ты можешь использовать:
count=0
ssh -t -t "$other_host" << ENDSSH
if [[ "${count}" == "0" ]]; then
output="string1"
else
output="string2"
fi
echo "\$output"
exit
ENDSSH
Мы используем \$output
так что он развернут на удаленном хосте не локально.
Лучше не использовать stdin (например, с помощью here-docs) для передачи команд ssh
,
Если вместо этого вы используете аргумент командной строки для передачи команд оболочки, вы можете лучше разделить то, что раскрывается локально, и то, что будет выполняться удаленно:
# Use a *literal* here-doc to read the script into a *variable*.
# Note how the script references parameter $1 instead of
# local variable $count.
read -d '' -r script <<'EOF'
[[ $1 == '0' ]] && output='zero' || output='nonzero'
echo "$output"
EOF
# The variable whose value to pass as a parameter.
# With value 0, the script will echo 'zero', otherwise 'nonzero'.
count=0
# Use `set -- '$<local-var>'...;` to pass the local variables as
# positional parameters, followed by the script code.
ssh localhost "set -- '$count'; $script"
Вы можете экранировать переменные, как сказал @anubhava, или, если вы получите слишком много переменных для экранирования, вы можете сделать это в два этапа:
# prepare the part which should not be expanded
# note the quoted 'EOF'
read -r -d '' commands <<'EOF'
if [[ "$count" == "0" ]]; then
echo "$count - $HOME"
else
echo "$count - $PATH"
fi
EOF
localcount=1
#use the unquoted ENDSSH
ssh me@nox.local <<ENDSSH
count=$localcount # count=1
#here will be inserted the above prepared commands
$commands
ENDSSH
напечатает что-то вроде:
1 - /usr/bin:/bin:/usr/sbin:/sbin