subprocess.Popen 和执行 ssh 命令的问题 [英] Issue with subprocess.Popen and executing ssh command

查看:37
本文介绍了subprocess.Popen 和执行 ssh 命令的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆