如何将 os.popen 设置为使用 Bash?

d3p*_*3pd 1 python bash operating-system subprocess

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

def engage_command(
    command = None
    ):
    #os.system(command)
    return os.popen(command).read()
Run Code Online (Sandbox Code Playgroud)

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

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

jfs*_*jfs 6

output = subprocess.check_output(command, shell=True, executable='/bin/bash')
Run Code Online (Sandbox Code Playgroud)

os.popen()是在subprocess模块方面实现的


我正在处理一个环境,在这个环境中我与许多环境变量等进行交互。

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

    也许,这是不很明显os.popen(),说文件

    打开一个管道到或从命令 cmd

    “打开管道”无法清楚地传达:“使用重定向的标准输入或输出启动新的 shell 进程”——您可以报告文档问题

    如有任何疑问;在证实,每次成功os.popen()调用创建一个新的子进程

  2. 子进程无法修改其父进程环境(通常)

考虑:

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())
Run Code Online (Sandbox Code Playgroud)

输出:

==value==

====
Run Code Online (Sandbox Code Playgroud)

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

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

output = check_output("\n".join(commands), shell=True, executable='/bin/bash')
Run Code Online (Sandbox Code Playgroud)

例子:

#!/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())
Run Code Online (Sandbox Code Playgroud)

输出:

==value==
==value==
Run Code Online (Sandbox Code Playgroud)

注意:$VAR这里不为空。

如果您需要动态生成新命令(基于之前命令的输出);它产生了几个问题,其中一些问题可以使用pexpectmodule: code example修复。

  • @d3pd:使用`os` 模块在这里什么也没有。单击链接:无论如何,`os.popen()` 在幕后使用了 `subprocess`。 (3认同)