我无法获得与bash相关或python子进程的信息,但结果有所不同:
I cannot get it it's bash related or python subprocess, but results are different:
>>> subprocess.Popen("echo $HOME", shell=True, stdout=subprocess.PIPE)municate() (b'/Users/mac\n', None) >>> subprocess.Popen(["echo", "$HOME"], shell=True, stdout=subprocess.PIPE)municate() (b'\n', None)为什么第二次只是换行符?争论在哪里消失?
Why in second time it's just newline? Where argument are falling off?
推荐答案subprocess.Popen()的第一个参数告诉系统要运行什么.
The first argument to subprocess.Popen() tells the system what to run.
当它是列表时,您需要使用shell=False.它恰好在Windows中如您所愿地起作用.但是在类Unix平台上,您只是传递了许多通常会被忽略的参数.实际上,
When it is a list, you need to use shell=False. It coincidentally happens to work as you hope in Windows; but on Unix-like platforms, you are simply passing in a number of arguments which will typically get ignored. Effectively,
/bin/sh -c 'echo' '$HOME'这只会导致第二个参数不被使用(在这里我使用单引号来强调它们只是静态字符串).
which simply causes the second argument to not be used for anything (where I use single quotes to emphasize that these are just static strings).
以我的拙见,在这种情况下,Python应该抛出一个错误.在Windows上也是如此.这是一个错误,应该捕获并报告.
In my humble opinion, Python should throw an error in this case. On Windows, too. This is an error which should be caught and reported.
(在相反的情况下,虽然指定了shell=False,但您传递的字符串不是有效命令的名称,但最终还是会得到一个错误,并且即使您对此有一个模糊的想法也很有意义发生了什么.)
(In the opposite case, where shell=False is specified but the string you pass in is not the name of a valid command, you will get an error eventually anyway, and it makes sense if you have even a vague idea of what's going on.)
如果您真的知道自己在做什么,则可以使第一个参数访问后续参数;例如
If you really know what you are doing, you could cause the first argument to access subsequent arguments; for example
/bin/sh -c 'printf "%s\n" "$@"' 'ick' 'foo' 'bar' 'baz'将在单独的行上打印foo,bar和baz. (零"参数-这里是'ick'-用于填充$0.)但这只是一个晦涩的推论;不要尝试将其用于任何用途.
would print foo, bar, and baz on separate lines. (The "zeroth" argument - here, 'ick' - is used to populate $0.) But this is just an obscure corollary; don't try to use this for anything.
此外,如果只想运行命令,则不应使用subprocess.Popen(). subprocess.run()文档将更详细地告诉您这一点.使用text=True,您将得到一个字符串而不是字节.
As a further aside, you should not use subprocess.Popen() if you just want a command to run. The subprocess.run() documentation tells you this in some more detail. With text=True you get a string instead of bytes.
result = subprocess.run('echo "$HOME"', shell=True, text=True, capture_output=True, check=True) print(result.stdout, result.stderr)当然,os.environ['HOME']允许您从Python内部访问$HOME的值.这也允许您避免shell=True,如果可以的话,通常应该这样做.
And of course, os.environ['HOME'] lets you access the value of $HOME from within Python. This also allows you to avoid shell=True which you usually should if you can.
更多推荐
subprocess.Popen("echo $ HOME" ...和subprocess.Popen(["echo",
发布评论