【问题标题】:Run BASH built-in commands in Python?在 Python 中运行 BASH 内置命令?
【发布时间】:2011-07-24 13:45:15
【问题描述】:

有没有办法从 Python 运行 BASH 内置命令?

我试过了:

subprocess.Popen(['bash','history'],shell=True, stdout=PIPE)

subprocess.Popen('history', shell=True, executable = "/bin/bash", stdout=subprocess.PIPE)

os.system('history')

及其许多变体。我想运行historyfc -ln

【问题讨论】:

  • 第二个对我来说很合适。它出了什么问题?
  • 运行一个 bash 进程并与之交互怎么样?对于长时间运行的命令或与 shell 交互(即在sudo 之后输入密码),它可能更简单且有用。我认为pexpect 可能适合这种需求。

标签: python bash command subprocess


【解决方案1】:

我终于找到了一个可行的解决方案。

from subprocess import Popen, PIPE, STDOUT
shell_command = 'bash -i -c "history -r; history"'
event = Popen(shell_command, shell=True, stdin=PIPE, stdout=PIPE, 
    stderr=STDOUT)

output = event.communicate()

感谢大家的意见。

【讨论】:

  • shell=True 在这里是多余的(它开始是不必要的/bin/sh)。您可以删除它并使用@lesmana's answer 中的列表参数
  • 不幸的是,'-r' 选项在打开 shell 后没有执行任何当前命令。 '-r' 选项将 ~/.bash_history 文件中的任何内容加载到您刚刚打开的新 shell 中。但是,~/.bash_history 文件通常仅在您关闭 shell 时更新(除非您的 .bashrc 中有 PROMPT_COMMAND hack)。由于您无法关闭当前正在运行的 shell(以获取要更新的历史文件),因此您很不走运。我还没有找到解决方法。
【解决方案2】:
subprocess.Popen(["bash", "-c", "type type"])

这会调用 bash 并告诉 bash 运行字符串 type type,后者会在参数 type 上运行内置命令 type

输出:type is a shell builtin

-c 之后的部分必须是一个字符串。这不起作用:["bash", "-c", "type", "type"]

【讨论】:

  • 这适用于“类型”和“别名”,但不适用于“历史”或“fc -ln”。
  • @duanedesign 他们确实可以工作,但是从子进程开始的 bash 会话已禁用其历史记录。这种行为是设计使然。您将不得不告诉 bash 以某种方式启用其历史记录。我记得前段时间在一些 stackexchange 网站上读过一个关于这个的问题。当我再次找到它时,我会报告。
  • 那里的描述建议只获取 $HOME/.bash_history,但这似乎不是最新的。我认为它只有在一个 shell 或者所有 shell? 退出时才被保存。
  • 您对“-c 之后的部分必须是一个字符串”的警告非常重要。我第一次错过了它,在我的情况下 suprocess.run(['bash', '-c', 'command command-that-shouldnt-exist'], check=True) 正确失败,而 suprocess.run(['bash', '-c', 'command', 'command-that-shouldnt-exist'], check=True) 工作得很好。
猜你喜欢
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多