python - subprocess.Popen 和执行 ssh 命令出现问题

标签 python python-2.7 subprocess

我正在使用 subprocess.Popen 执行操作系统命令。这是我试图在代码中模拟的内容:

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 的调用不起作用:

        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

第一种方法有效,但后一种方法对我来说似乎“更干净”。

为什么 Popen 不允许我在列表中指定参数?

最佳答案

当您使用shell=True时在 UNIX 上,您应该以字符串形式提供参数。当您提供列表时,subprocess将列表中的第一项解释为整个命令字符串,并将列表中的其余项目解释为传递给 shell 本身的参数,而不是您的命令。因此,在上面的示例中,您最终会得到如下结果:

/bin/sh -T filer < /dev/myscript -c "/usr/sbin/ssh"

绝对不是你的意思!

相反,当您使用shell=False时,如果您运行不带参数的单个命令,则只能传递字符串。如果您确实有参数,则必须将命令作为序列传递。您也不能通过 < 使用 shell 重定向。字符,因为不涉及 shell。

如果您想使用shell=False ,您可以使用stdin将文件句柄传递给 /dev/myscript 的关键字参数:

 f = open("/dev/myscript")
 p = subprocess.Popen(["/usr/bin/ssh", "-T", filer], stdout=subprocess.PIPE, stdin=f, shell=False)

何时传递字符串与何时传递序列的规则非常令人困惑,尤其是当您将 Windows 也纳入其中时。我会读documentation仔细地尝试理解这一切。查看 args 上的两个部分以及 shell 部分.

关于python - subprocess.Popen 和执行 ssh 命令出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25021347/

相关文章:

python - Beautiful Soup 4 CSS 同级选择器

python - 测试模块的所有符号是否已定义的快速方法,无需完整的单元测试覆盖

python - GitPython:获取尚未应用的远程提交列表

python - 使用计数将条件排除应用于 Pandas DataFrame

Python 元类冲突/类型错误

python - 在不创建僵尸进程的情况下停止 Flask 中的后台进程

Python参数解析器列表或元组的元组列表

python - 在 Python 中使用 WordCloud 更改单词颜色

python - 为什么 subprocess.Popen 参数长度限制小于操作系统报告的长度?

Python:子进程与 native API