从包含引号空格的shell变量向Python脚本传递参数
我通过一个bash脚本来调用一个python脚本,但在处理包含引号和空格的参数时遇到了麻烦。
我把要传给python脚本的参数放进一个bash变量里,比如说:
opt="-c start.txt"
opt+="--self 'name Na'"
然后用类似这样的方式来调用python脚本:
python test_args.py $opt
在python中打印sys.argv
时,我得到的是:
['test-args.py', '-c', 'start.txt', '--self', "'name", "Na'"]
而不是我预期的结果:
['test-args.py', '-c', 'start.txt', '--self', 'name Na']
我尝试在调用脚本时使用数组,比如:
python test_args.py ${opt[@]}
但结果却是:
['test-args.py', "-c start.txt --self 'name Na'"]
还有其他的解决办法吗?
3 个回答
-1
你在变量值里加空格的想法是不错的,但当这个值在命令行解析时被简单地展开时,空格的特殊意义就会消失,正如你看到的那样。你需要在命令行解析你的Python脚本之前先展开这个变量:
set -f
eval python test_args.py $opt
set +f
展开后会变成:
python test_args.py -c start.txt --self 'name Na'
这样就能正确解析,双引号也会恢复它们的特殊意义。
补充说明:我在eval周围加了set -f/+f(也就是-o/+o noglob)来禁用文件通配符,虽然在提问者的例子中这不是问题,但在使用eval时,这种情况并不少见。(还有一个更重要的警告是,绝对不要对用户输入使用eval,除非你非常小心,确保不会引发严重问题。如果你无法控制被eval的值,你就无法确定会发生什么。)
0
这就是 shlex 模块的用途。
shlex 类可以帮助我们轻松地编写词法分析器,适用于一些简单的语法,类似于 Unix 命令行的写法。这在编写小型语言时非常有用,比如在 Python 应用程序的运行控制文件中,或者用来解析带引号的字符串。
4
使用一个数组,但把每个参数当作数组中的一个单独元素来存储:
opt=(-c start.txt)
opt+=(--self 'name Na')
python test_args.py "${opt[@]}"
可以参考 BashFAQ #050。