在python中获取shell提示符

在python中获取shell提示符

我想在 python 脚本中获取 (zsh) shell 提示符。只需使用

import os
prompt = os.environ['PS1']

似乎不是正确的方法,因为PS1通常不会转发到子流程。以同样的方式env | grep PS在 shell 中失败。

所以我得出的结论是,我应该启动一个交互式 shell 作为子进程并查询它的提示符。从外壳我可以做

zsh -c -i 'echo $PS1'

(必须是单引号,双引号失败)

我尝试从 python(2.7) 中执行相同的操作,如下subprocess所示:

print subprocess.check_output(['-i','-c',r"'echo $PS1'"],executable="/bin/zsh")

这失败了

subprocess.CalledProcessError: Command '['-i', '-c', "'echo $PS1'"]' returned non-zero exit status 127

我认为这不是因为,$PS1而是由于我提供 echo-part 作为参数的方式,因为以这种方式回显裸字符串也会失败。

来回尝试各种组合我最终得到了

prompt =  subprocess.check_output("""zsh -c -i 'echo $PS1'""",shell=True,executable="/bin/zsh")

这似乎完成了这项工作,但对我来说似乎是错误的,因为这是启动一个 shell,并在该 shell 中使用 调用另一个 shell -c -i 'echo $PS1'

获取 shell 提示符的正确方法是什么?

答案1

print subprocess.check_output(['zsh','-i','-c','echo $PS1'])

从另一个 shell运行时zsh,周围的引号echo $PS1是必需的,以便整个字符串作为 后的单个参数传递-c。他们必须是单身的引号是因为在双引号中,第一个 shell 会展开$PS1

在 Python 中,整个命令是单个字符串,因此它像任何其他字符串一样被引用。添加第二组就像键入'echo $PS1'(带引号)一样zsh- shell 会查找名为 的可执行文件,但找不到'echo $PS1'

答案2

我认为正确的方法是调用子进程,如下所示:

>>> prompt = subprocess.check_output("""echo $PS1""",shell=True,executable="/bin/zsh")

然后你可以通过以下方式检查结果>>> prompt Enter ,或者你可以使用 call 直接查看结果:

>>> subprocess.call("""echo $PS1""",shell=True,executable="/bin/zsh")

所以你不需要调用zsh命令本身。

Popen可以使用以下方式进行交互通信:

>>> Popen(["/bin/zsh"], stdout=PIPE).communicate()[0]
SHELL_PROMPT% echo $PS1    
SHELL_PROMPT% exit  # exit to see the result of command   

有关此内容的更多信息,请参阅子流程

shell=True另请注意有关使用上面链接的警告:

警告:执行包含来自不受信任来源的未经处理的输入的 shell 命令会使程序容易受到 shell 注入的攻击,这是一个严重的安全缺陷,可能导致任意命令执行。因此,在命令字符串是从外部输入构造的情况下,强烈建议不要使用 shell=True:

>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
shell=False does not suffer from this vulnerability; the above Note may be helpful in getting code using shell=False to work.

相关内容