【问题标题】:What device are bash prompts written to?bash 提示写入什么设备?
【发布时间】:2025-12-09 10:20:03
【问题描述】:

我实际上并没有试图让这段特定的代码工作,但它的输出让我质疑提示的确切写入位置。在 Python 中考虑:

subprocess.run("bash", shell=True, stderr=subprocess.PIPE)

然后我输入fakecommand 并按回车键,然后输入EOF。它返回:

CompletedProcess(args='bash', returncode=127, stderr=b'bash: line 2: fakecommand: command not found\n')

这不会捕获stderr 中的提示,但它也不会像我预期的那样打印到屏幕上(没有像user@host 那样出现)。

我知道在 Python 中调用 bash 非常古怪。我的问题是为什么提示没有出现。

【问题讨论】:

  • 提示被写入标准错误,但它们不会被写入非交互式shell。
  • ...当您没有明确指定您希望您的 shell 具有交互性时,将根据其输出是否发送到 TTY 来确定,而管道不是。
  • 如果你在交互式 shell 中运行 bash 2> >(cat >&2),你会看到同样的结果——stderr 不是 TTY,所以没有提示。

标签: python bash


【解决方案1】:

您可以使用unbuffer 让您的 bash 副本认为 stderr 是一个 TTY,即使它真的是一个 FIFO;这将导致它发出提示,否则它会抑制它们。

subprocess.run(['unbuffer', 'bash'], stderr=subprocess.PIPE)

请注意,shell=True 已被删除——我们不想在另一个 bash 副本中启动一个 bash 副本

【讨论】:

  • 我知道为什么我们不应该使用shell=True;在编写测试代码时,这只是为了方便起见。但是,您提供的这段代码 sn-p 并没有真正做太多。它将打印一个提示,您可以输入一些文本,但唯一的出路是Ctrl-C,并且没有任何内容可检索。并不是说我真的在尝试使用此代码。只是在寻找你在 cmets 中回答的提示的答案。谢谢。尽管如此,我刚才描述的行为确实很奇怪,现在我也很好奇。
  • 如果行为的某个特定部分令人惊讶,请随时提出问题。
  • 是的。为什么你提供的代码会打印一个提示,你可以输入一些文本,但唯一的出路是 Ctrl-C 并且什么都无法检索?
  • 我确实说过问一个问题。你知道,作为一个问题。 :)
  • ...我不清楚您所说的“没有什么是可检索的”是什么意思。在回答之前,我想实际进行 sysdig 跟踪以确认我的理解的其他一些方面;正式的提问流程可以更轻松地提供经过研究的长篇回复(并鼓励其他人进行事实核查)。