如果我使用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时保留空格?

+1

“......我根本不使用引号”。这是一个错误。你需要(至少)用dbl-quotes包围所有变量名('$ VAR1'),即。 '“$ VAR1”'。祝你好运。 – shellter

+0

不幸的是,我通过带引号的参数传递的变量名仍然不能保留空白。 –

+1

在空格之前转义字符“\”? – L30n1d45

首先,我们重写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"   
}