Bash 在命令行上传递给程序的环境变量中带引号的字符串
我有一个在环境变量中放置带引号字符串的系统。此环境变量作为命令行参数传递给python程序,但带引号的字符串被拆分为多个单词,而不是保持在一起 例如: 在外壳中:Bash 在命令行上传递给程序的环境变量中带引号的字符串,bash,shell,Bash,Shell,我有一个在环境变量中放置带引号字符串的系统。此环境变量作为命令行参数传递给python程序,但带引号的字符串被拆分为多个单词,而不是保持在一起 例如: 在外壳中: $ export ARG_OPTIONS='--flag -a 31 --big_complicated_flag "How are you?"' 在bash脚本中: python args.py $ARG_OPTIONS 在python脚本中: import sys print sys.argv 结果是: ['args.py'
$ export ARG_OPTIONS='--flag -a 31 --big_complicated_flag "How are you?"'
在bash脚本中:
python args.py $ARG_OPTIONS
在python脚本中:
import sys
print sys.argv
结果是:
['args.py', '--flag', '-a', '31', '--big_complicated_flag', '"How', 'are', 'you?"']
这里重要的一点是,带引号的字符串被分割成多个部分,这不是程序所期望的参数。
我不能改变这个设置太多,所以任何想法将不胜感激
我尝试过的事情 Shell中的双引号 这是不正确的,因为整个变量作为单个参数传入。 然而,我期待这种行为,但我想我会尝试 Shell中的单引号 也不正确,但从我对单引号的理解来看是意料之中的 环境变量周围的双引号 此结果与原始结果相同 环境变量周围的单引号和双引号 也不正确 搞乱IFS 更改IFS分隔符并手动分隔环境变量中的参数:
export ARG_OPTIONS='--flag|-a|31|--big_complicated_flag|How are you?'
在shell脚本中:
IFS='|'
python args.py $ARG_OPTIONS
Result: ['args.py', '--flag', '-a', '31', '--big_complicated_flag', 'How are you?']
这会产生预期的输出,但它看起来很粗糙,而且以后容易混淆。显然,对于shell和环境变量之间的交互,我还不了解一些东西
为什么要把双引号中的单词分开?有没有更干净的方法来实现我的目标?而不是
python args.py $ARG_OPTIONS
您可能想使用
eval "python args.py $ARG_OPTIONS"
从eval的bash帮助中:
eval: eval [arg ...]
Execute arguments as a shell command.
Combine ARGs into a single string, use the result as input to the shell,
and execute the resulting commands.
简而言之,eval
再次评估它的参数;这会将一对双引号转换为影响分词的双引号
但是,请注意:此方法会带来安全风险-现在可以执行任意代码。在执行时,shell会执行几项操作。它将shell变量扩展为它们的值;应用元字符扩展(如“*”);插值。。。然后将所有内容传递给可执行文件。您修改IFR的想法是一个很好的解决方案。@dwork中详细介绍了这一点,…简短的回答是“使用数组”
arg_options=(-flag-a31——大的复杂的_标志“你好吗?”)
,然后python args.py“${arg_options[@]}”
会很好地工作。@Charles谢谢你找到了重复的,我很难知道到底要搜索什么。常见问题解答也很棒。如果不是通过无法处理数组的环境变量进行通信的话,数组的想法是可行的。接下来,我建议ARG\u OPTIONS=“--flag-a31--big\u-flag\”你好吗?\”;readarray-d“”arg_options<这会引入新的bug,其中一些会影响安全性。至少,让它eval“python args.py$ARG_OPTIONS”
;这更清楚地说明了它的作用,并且不会将字符串拆分为单词,并在将它们连接在一起并作为单个shell命令解析结果之前将它们作为全局展开。对于无法引用传递给eval
的字符串的具体示例,请运行cmd='printf“%s\n”“*”;eval$cmd
,并将其与eval“$cmd”
进行比较(任何查看此内容的人都应阅读;如果不是“你好”
,而是“阻止未经身份验证的用户登录$(rm-rf~)'$(rm-rf~)”
,则eval
将非常危险)。添加了双引号并提到了安全风险。@charlesduff啊,是的,这正是我想要的。我将标记为已接受,即使存在安全风险,因为我的输入不是来自外部来源。显然,关于shell脚本,我还有很多东西要学!
IFS='|'
python args.py $ARG_OPTIONS
Result: ['args.py', '--flag', '-a', '31', '--big_complicated_flag', 'How are you?']
python args.py $ARG_OPTIONS
eval "python args.py $ARG_OPTIONS"
eval: eval [arg ...]
Execute arguments as a shell command.
Combine ARGs into a single string, use the result as input to the shell,
and execute the resulting commands.