【问题标题】:Basic cygwin commands from python subprocess来自 python 子进程的基本 cygwin 命令
【发布时间】:2017-06-10 18:49:47
【问题描述】:

我想从 python 运行 cygwin 并执行 cygwin 命令。

我使用的是 Windows,所以我想在 cygwin 而不是 cmd 中运行命令。我正在使用 Python 3.6.1。

我只想知道如何运行基本命令,这样我就可以像ls 那样从那里工作。我试过了:

  • subprocess.call("E:/cygwin/bin/bash.exe", "ls")(类似这样,但不起作用)
  • @pstatix 建议的以下解决方案使用 Popen()。在 stdin.write(b'ls') 之后运行 stdin.close() 会导致 /usr/bin/bash: line 1: ls: command not found 错误

我能够做到以下几点:

  • 打开cygwin:subprocess.call("E:/cygwin/bin/bash.exe")

  • (在 Windows cmd 上运行命令:subprocess.call("dir", shell=True)

这种格式可以吗? 当我运行下一个 python 命令时,cygwin 会自动关闭,还是需要在此之前退出?

我对此比较陌生。

【问题讨论】:

  • 你还没有展示你的全套代码行。更新您的帖子以显示与我的答案类似的一系列行。我们需要看到这一切才能提供帮助。
  • 你的代码和上面几行就是我所拥有的。我试图弄清楚这是如何工作的,以便我可以在它的基础上构建并运行/编写其他命令,目前我真的没有别的东西了。
  • 您应该能够直接运行很多命令,而无需运行 bash 并写入其标准输入。 Unix 命令行主要由像/bin/ls 这样的小程序组成,对你来说可能是E:/cygwin/bin/ls.exe
  • @sandboxj 正如 eryksun 评论的那样,bash.exe 打开一个没有任何选项的空 shell(例如 /bash/bin); here 是一篇讨论 mintty.exe 与 bash.exe 的 SO 帖子,仅对此进行了解释。除此之外,我要求您添加代码的要求是完整添加它,例如我发布的答案。您只是发布了一些参考您尝试过的内容的要点。向我们展示完整的代码、缩进和所有内容!

标签: python windows bash shell


【解决方案1】:
from subprocess import Popen, PIPE

p = Popen("E:/cygwin/bin/bash.exe", stdin=PIPE, stdout=PIPE)
p.stdin.write("ls")
p.stdin.close()
out = p.stdout.read()
print (out)

【讨论】:

  • p.stdin.write("ls") 抛出错误:“TypeError:需要一个类似字节的对象而不是'str'”。似乎“ls”不是 .write() 的正确论点,还是我做错了什么?其他命令似乎有效。
  • @sandboxj 你用的是什么版本的 Python?要发送类似字节的内容,只需执行p.stdin.write(b'ls')。但是,Python 2.7.13 上的代码没有问题
  • 我使用的是 Python 3.6.1。使用 (b'ls') 提出的解决方案使 .write 行工作,但是当输入 p.std.in.close() 时,它奇怪地返回 /usr/bin/bash: line 1: ls: command not found。另外,当输入剩下的两行时,它最终会打印出b''
  • @sandboxj 你为什么写p.std.in.close()?在stdin 的中间没有.。您应该使用您正在测试的完整代码更新您发布的问题;我们可以从那里去。
  • 此代码在我使用管理员权限运行 Python 后有效。
【解决方案2】:
from subprocess import Popen, PIPE, STDOUT

p = Popen(['E:/cygwin/bin/bash.exe', '-c', '. /etc/profile; ls'], 
          stdout=PIPE, stderr=STDOUT)
print(p.communicate()[0]))

这将打开 bash,执行-c 之后提供的命令并退出。

您需要前置 . /etc/profile;,因为 bash 是以非交互模式启动的,因此没有初始化任何环境变量,您需要自己获取它们。

如果您通过 用户文件夹 中的 babun 软件安装了 cygwin(就像我一样),代码如下所示:

from subprocess import Popen, PIPE, STDOUT
from os.path import expandvars

p = Popen([expandvars('%userprofile%/.babun/cygwin/bin/bash.exe'), '-c', '. /etc/profile; ls'], 
          stdout=PIPE, stderr=STDOUT)
print(p.communicate()[0])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 2020-11-26
    • 2012-10-31
    • 1970-01-01
    • 2021-12-10
    相关资源
    最近更新 更多