【问题标题】:How to run bash commands using subprocess.run on windows [duplicate]如何在 Windows 上使用 subprocess.run 运行 bash 命令 [重复]
【发布时间】:2020-02-12 14:53:18
【问题描述】:

我想在 python 3.7.4 中使用 subprocess.run() 运行 shell 脚本和 git-bash 命令。当我在subprocess documentation page 上运行简单示例时,会发生这种情况:

import subprocess

subprocess.run(["ls", "-l"])

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\pycharm\project\envs\lib\subprocess.py", line 472, in run
    with Popen(*popenargs, **kwargs) as process:
  File "C:\pycharm\project\envs\lib\subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "C:\pycharm\project\envs\lib\subprocess.py", line 1178, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified


# it also fails with shell=True
subprocess.call(["ls", "-l"], shell=True)

'ls' is not recognized as an internal or external command,
operable program or batch file.
1

shell=True 的消息是来自 windows cmd 的消息,这表明子进程没有向 git-bash 发送命令。

我正在为 python 使用位于 project/envs/ 文件夹中的 conda 环境。我也安装了 git-bash。

我也尝试设置环境并得到同样的错误。

import os
import subprocess

my_env = os.environ.copy()
my_env["PATH"] = 'C:\Program Files\Git\;' + my_env["PATH"]
subprocess.run(['git-bash.exe', 'ls', '-l'], env=my_env)

Traceback (most recent call last):
  File "<input>", line 3, in <module>
  File "C:\pycharm\project\envs\lib\subprocess.py", line 472, in run
    with Popen(*popenargs, **kwargs) as process:
  File "C:\pycharm\project\envs\lib\subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "C:n\pycharm\project\envs\lib\subprocess.py", line 1178, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified

我可以通过指向 git-bash.exe 来运行它,但它返回一个空字符串而不是我目录中的文件

import subprocess
subprocess.run(['C:\Program Files\Git\git-bash.exe', 'ls', '-l'], capture_output=True)

CompletedProcess(args=['C:\\Program Files\\Git\\git-bash.exe', 'ls', '-l'], returncode=0, stdout=b'', stderr=b'')


subprocess documentation page 所示,我将不胜感激任何有关使其工作的最佳方式的建议。

【问题讨论】:

  • 如果你在windows cmd中运行ls -l,它可以工作吗?如果您在 windows cmd 中运行C:\Program Files\Git\git-bash.exe ls -l,它可以工作吗?如果他们不这样做,这些命令也不会通过 Python 运行。尝试先在windows cmd中运行一些命令,成功,再通过Python运行。
  • 在 cmd 中 ls -l 返回 'ls' is not recognized as an internal or external command, operable program or batch file, 就像 subprocess.call(["ls", "-l"], shell=True) 一样。运行C:\Program Files\Git\git-bash.exe ls -l 会打开一个 git bash 终端,然后它会快速关闭,而不会打印来自ls 的结果,或者它可能只是立即关闭,所以我看不到打印。如果我更改为C:\Program Files\Git\git-bash.exe sleep 5,git 终端甚至不会保持打开状态 1 秒钟,这表明它没有运行命令。

标签: python python-3.x subprocess python-3.7


【解决方案1】:

试试这个

p = subprocess.Popen(("ls", "-l"), stdout=subprocess.PIPE)
nodes = subprocess.check_output(("grep"), stdin=p.stdout)
p.wait()

【讨论】:

  • 当我尝试定义 p 时,我得到相同的 FileNotFoundError,但它从第 775 行开始,因为 run 只是调用 popen
  • 打印输出并使用subprocess查看ls时正在使用的目录。
  • 由于ls 似乎没有运行,因此没有要打印的输出。我可以运行subprocess.run(['dir'], shell=True),它显示Directory of C:\pycharm\project
【解决方案2】:
  • ls 是用于列出文件和目录的 Linux shell 命令
  • dir 是用于列出文件和目录的 Windows 命令行命令

尝试在 Windows 命令行中运行 dir。如果可行,请尝试使用 python 子进程运行相同的命令:

import subprocess

subprocess.run(["dir"])

【讨论】:

  • 我得到了同样的FileNotFoundError: [WinError 2] . . .。但是当我运行subprocess.run(['dir'], shell=True) 时,在cmd 打印中运行dir 的结果。但是,我想使用 linux 命令,这样我也可以在 linux 服务器上运行代码。
【解决方案3】:

我发现我可以使用...Git\bin\bash.exe 而不是...\Git\git-bash.exe 来运行命令,如下所示:

import subprocess
subprocess.run(['C:\Program Files\Git\\bin\\bash.exe', '-c','ls'], stdout=subprocess.PIPE)

CompletedProcess(args=['C:\\Program Files\\Git\\bin\\bash.exe', '-c', 'ls'], returncode=0, stdout=b'README.md\n__pycache__\nconda_create.sh\nenvs\nmain.py\ntest.sh\nzipped\n')

【讨论】:

  • 可能的替代解决方案:如果它不是内置的 bash,它可能可以通过其 Windows 路径调用(例如 r'C:\Program Files\Git\bin\ssh.exe')(未经测试!)
  • 这是一个粗略的解决方法;正确的解决方案是使用executable 关键字参数告诉subprocess 使用哪个shell。
【解决方案4】:

对于具有 Windows 操作系统的机器,请尝试以下操作

import subprocess
subprocess.run(["dir", "/p"], shell=True)

“ls”替换为“dir”,“-l”替换为“/l”,“shell”设置为true

对于具有 Linux/Mac 操作系统的机器,请尝试以下操作

import subprocess
subprocess.run(["ls", "-l"])

【讨论】:

  • 这似乎只是重复了以前的旧答案中的信息。
猜你喜欢
  • 2021-11-19
  • 1970-01-01
  • 2019-08-13
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2011-03-11
  • 1970-01-01
  • 2012-03-28
相关资源
最近更新 更多