使用-c调用python时使用sys.argv
考虑以下简短的python(3.8)代码段:使用-c调用python时使用sys.argv,python,python-3.x,subprocess,argparse,Python,Python 3.x,Subprocess,Argparse,考虑以下简短的python(3.8)代码段: 导入子流程 def call_subprocess_命令(*命令:str): 将subprocess.Popen(args=command,stdout=subprocess.PIPE,text=True)作为进程: 对于iter中的线路(process.stdout.readline,“”): 打印(行) 调用_subprocess_命令(“python”、“-c”、“import sys;print(sys.argv)”、“--test”、“fo
导入子流程
def call_subprocess_命令(*命令:str):
将subprocess.Popen(args=command,stdout=subprocess.PIPE,text=True)作为进程:
对于iter中的线路(process.stdout.readline,“”):
打印(行)
调用_subprocess_命令(“python”、“-c”、“import sys;print(sys.argv)”、“--test”、“foo”)
这将打印['-c','-test',foo']
。我希望它只打印['--test',foo']
我之所以需要它,是因为我正在动态计算要在docker容器中运行的命令。
但是,被调用代码的cli解析器总是中断,因为它接收到“-c”参数,它不知道如何处理该参数:
call_subprocess_命令(“python”、“-c”,
“导入argparse;parser=argparse.ArgumentParser();parser.add_参数('test');print(parser.parse_args())”,
“--测试”,“foo”)
这将导致将用法打印到stderr,并将“-c”解析为“test”的值:
我目前的解决方法是只使用关键字参数(“--test”),但如果可能的话,我真的希望去掉“-c”
call_subprocess_命令(“python”、“-c”,
“导入argparse;parser=argparse.ArgumentParser();parser.add_参数('--test');print(parser.parse_args())”,
“--测试”,“foo”)
这会产生我想要的结果:
名称空间(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")
因此,我的问题是:
sys.argv
中存在的“-c”参数如注释中所述,
argparse
使用sys.argv[0]
作为prog
并解析sys.argv[1://code>
如果我指定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']
如注释中所述,
argparse
使用sys.argv[0]
作为prog
并解析sys.argv[1://code>
如果我指定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]
始终是调用当前可执行文件的名称(在操作系统级别也是如此,因此程序的行为可能会因启动时使用的名称而异)。因此,这是正常的,在解析参数时会忽略它,但在错误消息中(您希望消息以当前使用的可执行文件名开头)除外。这是类似于busybox
的程序的一种功能,可以使用数百个名称启动,取决于您是否希望它像ls
或cp
或sh
等那样工作。为什么决定让python-c'…'
将-c
放在argv[0]
槽中,这是我想通过python票证跟踪器搜索的原因之一,除非已经给出了源代码中的注释。也就是说,它不是“有时忽略“-c”,有时也不是”;argparse总是忽略打印帮助上下文之外的argv[0]
,这正是它应该做的。请记住,sys.argv[0]
始终是调用当前可执行文件的名称(在操作系统级别也是如此,因此程序的行为可能会因启动时使用的名称而异)。因此,这是正常的,在解析参数时会忽略它,但在错误消息中(您希望消息以当前使用的可执行文件名开头)除外。这是类似于busybox
的程序的一种功能,可以使用数百个名称启动,取决于您是否希望它像ls
或cp
或sh
等那样工作。为什么决定让python-c'…'
将-c
放在argv[0]
槽中,这是我想通过python票证跟踪器搜索的原因之一,除非已经给出了源代码中的注释。也就是说,它不是“有时忽略“-c”,有时也不是”;argparse总是忽略打印帮助上下文之外的argv[0]
,这正是它应该做的。谢谢,我知道通常sys.argv[0]就是程序。在本例中,我希望它是python
或python-c
,而不仅仅是-c
。谢谢,我知道通常sys.argv[0]是程序。在本例中,我希望它是python
或python-c
,而不仅仅是-c
。