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