subprocess.Popen 和执行 ssh 命令的问题 [英] Issue with subprocess.Popen and executing ssh command
问题描述
我正在使用 subprocess.Popen 来执行 OS 命令.这是我试图在我的代码中模拟的内容:
I am using subprocess.Popen to execute an OS command. Here is what I am trying to emulate in my code:
ssh -T myhost < /path/to/some/file
它像这样工作得很好:
def runWorkerCode(filer, filename):
command = "/usr/bin/ssh -T " + filer + " < /devel/myscript"
try:
p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
out, _ = p.communicate()
except Exception:
print "Error: %s" % Exception
sys.exit(1)
return out.rstrip().split('\n')
但是以下对 Popen 的调用不起作用:
But the following calls to Popen do not work:
p = subprocess.Popen(["/usr/bin/ssh", "-T", filer, "<", "/devel/myscript"], stdout=subprocess.PIPE, shell=True)
p = subprocess.Popen(["/usr/bin/ssh -T", filer, "< /devel/myscript"], stdout=subprocess.PIPE, shell=True)
我尝试了一些其他组合,但我唯一可以开始工作的方法是定义命令变量并将其提供给 Popen()
.我也试过 shell=False
.
I tried a few other combinations but only method I can get to work is defining the command variable and only providing it to Popen()
. I've also tried shell=False
.
第一种方法有效,但后一种方法对我来说似乎更干净".
The first method works but the latter approach seems "cleaner" to me.
为什么 Popen
不允许我在列表中指定参数?
Why doesn't Popen
allow me to specify the arguments in a list?
推荐答案
当您在 UNIX 上使用 shell=True
时,您应该以字符串形式提供参数.当您提供列表时,subprocess
将列表中的第一项解释为您的整个命令字符串,并将列表中的其余项解释为传递给 shell 本身的参数,而不是您的命令.所以在你上面的例子中,你会得到这样的结果:
When you use shell=True
on UNIX, you should provide your arguments as a string. When you provide a list, subprocess
interprets the first item in the list as your entire command string, and the rest of the items in the list as arguments passed to the shell itself, rather than your command. So in your example above, you're ending up with something like this:
/bin/sh -T filer < /dev/myscript -c "/usr/sbin/ssh"
绝对不是你的意思!
相反,当您使用 shell=False
时,如果您正在运行没有参数的单个命令,您只能传递一个字符串.如果您确实有参数,则必须将命令作为序列传递.您也不能通过 <
字符使用 shell 重定向,因为不涉及 shell.
Conversely, when you use shell=False
, you can only pass a string if you're running a single command with no arguments. If you do have arguments, have to pass the comamnd as a sequence. You also can't use shell redirection via the <
character, because there is no shell involved.
如果你想使用 shell=False
,你可以使用 stdin
关键字参数将文件句柄传递给 /dev/myscript
:
If you want to use shell=False
, you can use the stdin
keyword argument to pass a file handle to /dev/myscript
:
f = open("/dev/myscript")
p = subprocess.Popen(["/usr/bin/ssh", "-T", filer], stdout=subprocess.PIPE, stdin=f, shell=False)
何时传递字符串与何时传递序列的规则非常令人困惑,尤其是当您将 Windows 也纳入其中时.我会仔细阅读 文档 以尝试理解所有内容.查看 args
部分和 shell
部分.
The rules for when to pass a string vs. when to pass a sequence are pretty confusing, especially when you bring Windows into the mix as well. I would read the documentation carefully to try to understand it all. Check out both the section on args
and the section on shell
.
这篇关于subprocess.Popen 和执行 ssh 命令的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!