【问题标题】:Robustly identify which shell is running可靠地识别正在运行的 shell
【发布时间】:2013-03-26 13:15:06
【问题描述】:

我有一个 Python 程序需要执行不同的进程(为此我使用 subprocess.Popen)。我需要这个执行来表现得好像用户在 shell 命令提示符下键入了以下内容:

$ source path/to/some_file
$ ./some_program

我希望我将使用shell=True 和某种形式的命令链接首先运行source,然后执行程序。但是,我面临以下问题:

启动我的 Python 程序的 shell 可以是 bashshtcsh(或者可能是 csh 的其他形式)。我需要根据正在运行的 shell 获取不同的some_file。有没有办法确定这一点?在 Python 中或通过在 Popen(..., shell=True) 中运行某些东西,两者都可以。

我正在考虑编写某种“shell polyglot”来从不同的 shell 中获得不同的输出,但是我的 shell 技能(尤其是在 csh 中)不能胜任这样的任务。我有什么选择?

【问题讨论】:

  • 您可以通过使用executable 参数和shell=True 来强制使用特定的shell。
  • 在 Unix 上,无论用户实际使用哪个 shell,使用的 shell 默认为 /bin/sh。
  • @Cairnarvon,是的,但是 /bin/sh 在不同的 linux 上被符号链接到不同的东西。
  • 不鼓励使用shell=True..
  • @PavelAnossov,/bin/sh 是 POSIX 的一部分;如果替代品不提供其功能的超集,它们就会损坏。我不知道有任何类似 Unix 的东西。

标签: python shell popen


【解决方案1】:

subprocess.Popen() 使用哪个 shell 不是由用于启动 Python 的父 shell 决定的。相反,Python 使用的 shell 默认始终为 /bin/sh,如果需要,您可以通过在 Popen() 中显式指定可执行文件来更改它。

但实际上,任何给定的 shell 脚本都可以针对一种特定类型的 shell 编写。假设它是bash。然后,您可以通过编写这样的 shell 脚本来简单地忽略 Python 端的这些细节:

#!/usr/bin/env bash
source path/to/some_file
exec ./some_program

你去吧:一个完整​​的启动器脚本,它在开始时切换到 bash,获取必要的位,然后启动你的程序。任何合理的 shell 都应该能够运行它,所以现在您不必担心 Python 调用了哪个 shell...另外,您还有一种更可重复的方式来在 Python 之外启动您的程序。

【讨论】:

    【解决方案2】:

    ..生成 shell 然后与之通信呢?

    我的意思是,像这样:

    proc = subprocess.Popen(['/bin/bash'], stdin=PIPE, stdout=PIPE)
    proc.communicate("source path/to/some_file\n"
                     "./some_program\n")
    

    由于您想在特定的 shell 中执行两个命令,我认为这将是您拥有的最佳解决方案。

    否则,您可能会发现您的 shell 接受诸如“初始化脚本”和“初始命令”之类的参数;在这种情况下,如果你只需要使用那个特定的 shell,你应该使用它们;例如,bash 接受 --init-file file-c command 来完成这项工作(将加载 --init-file 而不是 bashrc)。

    【讨论】:

      猜你喜欢
      • 2020-08-16
      • 1970-01-01
      • 2011-07-24
      • 2011-05-21
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      相关资源
      最近更新 更多