【问题标题】:How can os.popen be set to use Bash?如何将 os.popen 设置为使用 Bash?
【发布时间】:2016-02-03 19:32:13
【问题描述】:

我有以下用于在 Python 中执行系统命令的函数:

def engage_command(
    command = None
    ):
    #os.system(command)
    return os.popen(command).read()

我正在使用os 模块而不是subprocess 模块,因为我正在处理一个单一的环境,在该环境中我与许多环境变量等进行交互。

如何将 Bash 与这种类型的函数一起使用,而不是默认的 sh shell?

【问题讨论】:

    标签: python bash operating-system subprocess


    【解决方案1】:
    output = subprocess.check_output(command, shell=True, executable='/bin/bash')
    

    os.popen() is implemented in terms of subprocess module.


    我正在处理一个与许多环境变量等交互的单一环境。

    1. 每个os.popen(cmd) 调用都会创建一个新 /bin/sh 进程,以运行cmd shell 命令。

      或许,从the os.popen() documentation that says看不明显:

      打开与命令cmd之间的管道

      “打开管道” 无法清楚地沟通:“使用重定向的标准输入或输出启动新的 shell 进程”——你可以 report a documentation issue。

      如有任何疑问; source 确认每个成功的 os.popen() 调用都会创建一个新的子进程

    2. the child can't modify its parent process environment (normally).

    考虑:

    import os
    #XXX BROKEN: it won't work as you expect
    print(os.popen("export VAR=value; echo ==$VAR==").read())
    print(os.popen("echo ==$VAR==").read())
    

    输出:

    ==value==
    
    ====
    

    ==== 表示第二个命令中的$VAR 为空,因为第二个命令在与第一个命令不同的/bin/sh 进程中运行。

    要在单个进程中运行多个 bash 命令,请将它们放在脚本中或作为字符串传递:

    output = check_output("\n".join(commands), shell=True, executable='/bin/bash')
    

    例子:

    #!/usr/bin/env python
    from subprocess import check_output
    
    output = check_output("""
        export VAR=value; echo ==$VAR==
        echo ==$VAR==
        """, shell=True, executable='/bin/bash')
    print(output.decode())
    

    输出:

    ==value==
    ==value==
    

    注意:$VAR 此处不为空。

    如果您需要动态生成新命令(基于先前命令的输出);它会创建several issues,并且可以使用pexpect 模块修复一些问题:code example。

    【讨论】:

    • 感谢您的建议。正如我在问题中提到的,我正在与很多环境变量以及诸如此类的东西进行交互,因此,就我的目的而言,os 模块是我正在尝试使用的。
    • @d3pd: 使用os 模块在这里什么都没有。点击链接:os.popen() 在后台使用subprocess。
    • @JFSebastian 好的,感谢您澄清这一点。您是否认为可以包含一个示例来说明如何使用这种方法来设置和使用环境变量? -- 可能类似于以下内容:export MY_DIRECTORY="~/test", ls "${MY_DIRECTORY}"
    • @d3pd:我已经更新了答案以显示 envvars 在多个命令中的行为方式。
    • @JFSabastian 非常感谢您提供的这些清晰而有用的细节。您的解决方案阐明了 os.popen 的子进程性质,并展示了如何将 Bash 与子处理一起使用。 (您是否碰巧知道是否有某种方法可以实现维护从 Python 创建和访问的子进程的 Bash 环境的存在的想法?)
    猜你喜欢
    • 1970-01-01
    • 2015-11-07
    • 2015-11-03
    • 2018-01-29
    • 2015-05-15
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多