Bash - 输出时参数不应被解析为 bash

Bash - 输出时参数不应被解析为 bash

我有 2 个 Shell 脚本。第一个触发第二个并添加一些参数。第二个脚本调用命令并将第一个脚本中的参数添加为该命令的参数。

第一个看起来像:

#!/usr/bin/env bash

ADDITIONAL_ARGUMENTS='--set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"'

SUPER_PARAMS=${ADDITIONAL_ARGUMENTS} my_second_script.sh

然后,第二个脚本执行以下操作:

#!/usr/bin/env bash

randomBinary --some-hardcoded-parameters \
             "${SUPER_PARAMS}"

我期望得到的是以下输出:

randomBinary --some-hardcoded-parameters --set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"

但相反,调用看起来像:

randomBinary --some-hardcoded-parameters '--set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}"'

我尝试了 2 天正确引用参数,但没有结果。

答案1

要存储多个参数,请使用数组,而不是标量变量。

additional_arguments=(
  --set
  'args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}'
)
randomBinary --some-hardcoded-parameters "${additional_arguments[@]}"

请注意,由于环境变量是非 NUL 字节的字符串,因此如果您想通过环境将数组定义传递给另一个命令,则需要进行一些编码。

ksh, bash,zsh或者yash您可以使用:

ARRAY_DEFINITION="$(typeset -p additional_arguments)" my_second_script.sh

将数组定义导出到调用脚本的环境变量中。

eval "$ARRAY_DEFINITION"在调用的脚本中进口该数组定义。

请注意,重要的是,代码是在与生成代码的语言环境相同的语言环境中并使用相同的 shell 进行计算的。

另请注意,如果在函数内部评估数组定义,则该数组将是该函数的本地数组。

有些 shell 喜欢rc,esfish允许导出数组(在内部使用它们自己的编码)。

在这里,将信息作为参数传递给被调用的脚本会更容易,因为这是一个数组。

在调用脚本中:

my_second_script.sh "${additional_arguments[@]}"

在调用的脚本中:

randomBinary --some-hardcoded-parameters "$@"

或者调用被调用的脚本,.以便它共享调用者的 shell 变量,这样您就不需要使用环境在执行过程中传递该数据。

答案2

这里,

randomBinary --some-hardcoded-parameters "${SUPER_PARAMS}"

SUPER_PARAMScontains --set "args={/bin/bash,-c,cd /var/www && sudo -u www-data bash scripts/system/update.sh}",并且由于它被引用,因此它按原样传递。如果不加引号,它将在空格上分割为五个字符串--set, "args={/bin/bash,-c,cd, /var/www, &&, sudo -u www-data bash scripts/system/update.sh}",并且这些字符串将作为参数传递。

看来您希望变量内的引号也被解释,这需要添加另一层 shell 解析,或者通过eval或 运行该东西bash -c '...'

测试脚本在这里:

$ cat test.sh
#!/bin/bash    
ARGS='--set "args={this, that && that}"'
./args.sh $ARGS
eval "./args.sh $ARGS"

印刷:

<!-- language: lang-none -->
$ bash test.sh
5 args: <--set> <"args={this,> <that> <&&> <that}"> 
2 args: <--set> <args={this, that && that}> 

(脚本args.sh打印的数字是不同参数的数量,参数本身打印在<...>

请注意,它将eval执行例如任何命令替换,因此它会打开任意代码执行。通常,最好将论点放在一个贝壳阵列相反,但在这里您将它们从一个脚本传递到另一个脚本,因此效果不太好。请参阅“如何将命令存储在变量中?”部分。在这个关于处理空白的答案

Bash 指南中的分词,您还可以使用set -x它来查看 shell 实际运行的命令。

相关内容