【问题标题】:sys.argv when calling python with -c使用 -c 调用 python 时的 sys.argv
【发布时间】:2020-03-25 02:24:06
【问题描述】:

考虑以下短python(3.8)sn-p:

import subprocess


def call_subprocess_command(*command: str):
    with subprocess.Popen(args=command, stdout=subprocess.PIPE, text=True) as process:
        for line in iter(process.stdout.readline, ""):
            print(line)



call_subprocess_command("python", "-c", "import sys; print(sys.argv)", "--test", "foo")

这将打印['-c', '--test', 'foo']。我希望它只打印['--test', 'foo']

我需要这个,因为我正在动态计算要在 docker 容器内运行的命令。 但是,被调用代码的 cli 解析器总是会中断,因为它接收到“-c”参数,它不知道如何处理:

call_subprocess_command("python", "-c", 
"import argparse; parser=argparse.ArgumentParser(); parser.add_argument('test'); print(parser.parse_args())",
 "--test", "foo")

这导致用法被打印到 stderr,并将“-c”解析为“test”的值:

usage: -c [-h] test
-c: error: unrecognized arguments: --test

我目前的解决方法是使用仅限关键字的参数(“--test”),但如果可能的话,我真的很想摆脱那个“-c”。

call_subprocess_command("python", "-c", 
"import argparse; parser=argparse.ArgumentParser(); parser.add_argument('--test'); print(parser.parse_args())",
 "--test", "foo")

这就是我想要的结果:

Namespace(test='foo')

我不太明白为什么会这样,因为它现在似乎忽略了“-c”。 如果我添加另一个它不知道的参数,例如“--bar”,它再次崩溃,即使“-c”也是一个它不知道的参数:

call_subprocess_command("python", "-c",
 "import argparse; parser=argparse.ArgumentParser(); parser.add_argument('--test'); print(parser.parse_args())",
 "--test", "foo", "--bar")
usage: -c [-h] [--test TEST]
-c: error: unrecognized arguments: --bar

所以我的问题是:

  1. 如何摆脱子进程'sys.argv 中存在的“-c”参数?
  2. 为什么 argparse 有时可以忽略“-c”,有时却不能?

【问题讨论】:

  • 请记住,sys.argv[0] 始终是调用当前可执行文件的名称(在操作系统级别也是如此,因此程序的行为可能会根据它们启动的名称而有所不同)。所以这是正常的,并且出于解析参数的目的而忽略它是正常的,except 在错误消息中(您希望消息以您当前使用的可执行文件名称开头)。
  • 这是busybox 之类的程序的工具,可以以数百个名称启动,具体取决于您是否希望它像lscpsh 等等.为什么决定让python -c '...'-c 放入argv[0] 插槽是我想通过Python 票证跟踪器搜索以找到理由的原因,除非已经给出了源中的评论。
  • 也就是说,它不是“有时忽略“-c”,有时不忽略”; argparse always 在打印帮助上下文之外忽略 argv[0],这正是它应该做的。

标签: python python-3.x subprocess argparse


【解决方案1】:

如 cmets 中所述,argparse 使用 sys.argv[0] 作为 prog 并解析 sys.argv[1:]

如果我指定prog 参数,这可能会更清楚,然后替换默认的'-c':

1119:~/mypy$ python3 -c 'import argparse; p=argparse.ArgumentParser(prog="PROG");print(p.parse_args())' --test foobar
usage: PROG [-h]
PROG: error: unrecognized arguments: --test foobar

在正常的脚本使用中,sys.argv[0] 是脚本的名称。这里的“脚本名称”是“-c”。

使用与sys.argv 相呼应的脚本:

1119:~/mypy$ python3 echo.py --test foobar
['echo.py', '--test', 'foobar']

【讨论】:

  • 谢谢,我知道通常 sys.argv[0] 是程序。在这种情况下,我希望它是 pythonpython -c,而不仅仅是 -c
猜你喜欢
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 2017-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-28
相关资源
最近更新 更多