【问题标题】:Passing arguments to a Python script from a shell variable containing quoted spaces从包含引号的空格的 shell 变量将参数传递给 Python 脚本
【发布时间】:2013-01-15 17:07:10
【问题描述】:

我正在通过 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'"]

还有其他想法吗?

【问题讨论】:

  • 也许 this 会有所帮助(查看 eval 解决方案)。

标签: python bash quotes spaces


【解决方案1】:

使用数组,但将每个参数作为单独的元素存储在数组中:

opt=(-c start.txt)
opt+=(--self 'name Na')

python test_args.py "${opt[@]}"

BashFAQ #050

【讨论】:

  • 这正是我最后想出的,谢谢你写出来!
【解决方案2】:

这就是shlex 模块的用途。

shlex 类使编写词法分析器变得容易 类似于 Unix shell 的语法。这通常很有用 用于编写小型语言,(例如,在运行控制文件中 Python 应用程序)或用于解析带引号的字符串。

【讨论】:

    【解决方案3】:

    您在变量值中嵌入空格的本能很好,但是当您在命令行解析期间简单地扩展该值时,它们的特殊含义就会丢失,如您所见。在解析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 (aka -/+o noglob) 以禁用文件通配,尽管这在 OP 的示例中不是问题,这不是 eval 的闻所未闻的问题。 (另一个更强烈的警告是永远不要评估用户输入,除非你非常小心以确保它不会爆炸成令人讨厌的东西。如果你不控制被评估的值,你不能确定什么会发生。)

    【讨论】:

    • 请不要使用eval,它因引起奇怪的错误而享有当之无愧的声誉。例如,用opt="-c start.txt --self 'name * Na'" 试试这个并尝试解释结果。
    • 我拒绝您在 OP 上下文中的风险评估,该 OP 显示脚本控制要评估的值的内容,但同意需要警告。如果您建议使用 set -f ... set +f 包围 eval 以禁用文件通配符,可能会更有帮助。 (当然,这是你暗示的问题。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-29
    • 2022-11-14
    相关资源
    最近更新 更多