如果我使用ssh远程执行其中一个脚本,如何在从一个脚本向另一个脚本传递参数时保留空格?
问题描述:
我在将参数与空白从一个bash脚本传递到另一个bash脚本时会出现问题,这个脚本将通过ssh远程运行。我有一个剧本,create-node.sh看起来像这样:如果我使用ssh远程执行其中一个脚本,如何在从一个脚本向另一个脚本传递参数时保留空格?
# create-node.sh
#!/bin/bash
function set_node_env_variables {
docker-machine ssh remote-machine 'bash -s' < ./set-env-variables.sh \
$ENV_VARIABLE_ONE \ # "foo bar"
$ENV_VARIABLE_TWO \ # feefi
$ENV_VARIABLE_THREE \ # "fo fum"
$ENV_VARIABLE_FOUR # huffpuff
}
create-node.sh将参数传递给set-env-variables.sh,这是远程运行使用ssh,看起来像这样:
# set-env-variables.sh
#!/bin/bash
i=0
argv=()
for arg in "[email protected]"; do
argv[$i]="$arg"
i=$((i + 1))
done
echo "export ENV_VARIABLE_ONE=${argv[0]}" >> /root/.profile #expected: "foo bar"; actual: foo
echo "export ENV_VARIABLE_TWO=${argv[1]}" >> /root/.profile #expected: feefi; actual: bar
echo "export ENV_VARIABLE_THREE=${argv[2]}" >> /root/.profile #expected: "fo fum"; actual: feefi
echo "export ENV_VARIABLE_FOUR=${argv[3]}" >> /root/.profile #expected: huffpuff; actual: fo
带空格或特殊字符的环境变量在机器上用双引号存储,它将使用ssh执行set-env-variables.sh,否则我根本不使用引号。
如何在将参数从create-node.sh传递给set-env-variables.sh时如何在使用ssh远程执行set-env-variables.sh时保留空格?
答
首先,我们重写set-env-variable
来简化它。 (真的,它没有设置任何东西;它只是生成一个可以设置环境变量的脚本,但我们会忽略它。)您不需要创建argv
;你可以直接使用位置参数。
#!/bin/bash
{
printf 'export ENV_VARIABLE_ONE="%q"\n' "$1"
printf 'export ENV_VARIABLE_TWO="%q"\n' "$2"
printf 'export ENV_VARIABLE_THREE="%q"\n' "$3"
printf 'export ENV_VARIABLE_FOUR="%q"\n' "$4"
} >> /root/.profile
(使用%q
,以确保该变量的值是引用正确地在命令中使用。例如,包含双引号的值需要有逃跑了,这样它不会误关闭在export
命令的双引号:export foo="hi\"there"
与export foo="hi"there"
)
接下来,请务必正确引用您的扩展的功能(和,也没有必要从标准输入读取脚本;你只需要把它作为第一个。参数为bash
):
set_node_env_variables() {
docker-machine ssh remote-machine \
bash ./set-env-variables.sh \
"$ENV_VARIABLE_ONE" \
"$ENV_VARIABLE_TWO" \
"$ENV_VARIABLE_THREE" \
"$ENV_VARIABLE_FOUR"
}
“......我根本不使用引号”。这是一个错误。你需要(至少)用dbl-quotes包围所有变量名('$ VAR1'),即。 '“$ VAR1”'。祝你好运。 – shellter
不幸的是,我通过带引号的参数传递的变量名仍然不能保留空白。 –
在空格之前转义字符“\”? – L30n1d45