【问题标题】:Run consecutive Shell commands in Python-Subprocess在 Python-Subprocess 中运行连续的 Shell 命令
【发布时间】:2020-07-25 09:31:19
【问题描述】:

这些是我尝试运行的一些依赖命令。我的期望是将当前文件夹更改为abc 和列表文件。

同样设置z=88后,会打印z

import subprocess
cmd_list = []
cmd_list.append("cd ./abc")
cmd_list.append("ls")
cmd_list.append("export z=88")
cmd_list.append("echo $z")

my_env = os.environ.copy()
for cmd in cmd_list:
    sp = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=my_env, shell=True,text=True)

但无法获得lsecho $z 的任何输出

【问题讨论】:

  • 命令正在子进程中运行。他们所做的更改对父 Python 进程没有任何影响。
  • 导出的变量只被shell进程的子进程继承,不会回到Python进程,也不会被Python进程的其他子进程继承。

标签: python subprocess environment-variables


【解决方案1】:

您无法通过多次调用subprocess.Popen() 来执行此操作。每次调用都会创建一个新的子进程,并且它们对其环境所做的更改不会传播回 Python 进程。

您可以通过将所有命令连接到一个命令行中来做到这一点,由bash -c 运行。

cmd = 'cd abc; ls; export z=88; echo $z'
subprocess.Popen(['bash', '-c', cmd], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=my_env,text=True)

导出z 也没有任何意义,因为您没有运行任何使用环境变量的shell 子进程。只需使用z=88 分配一个普通的shell 变量。

【讨论】:

  • 你确定stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPEcapture_output 一起工作吗?
  • 不是真的,我只是从问题中复制了它。我删除了它。我还删除了shell=True,它在第一个参数是列表时没有用。
  • 是的,我错误地添加了capture_output。 @Barmar有什么办法可以拆分该命令吗?因为例如,假设第一个命令成功运行而第二个没有成功,那么我应该恢复第一个命令的结果。
  • 您可以使用&& 而不是; 分隔命令,这样下一个命令只有在前一个命令成功时才会运行。
最近更新 更多