从包含引号空格的shell变量向Python脚本传递参数

1 投票
3 回答
4728 浏览
提问于 2025-04-17 14:19

我通过一个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

撰写回答