首页 > 解决方案 > 如何使用 Python 脚本将目录添加到 Fish shell PATH?

问题描述

从在 Fish shell 上运行并支持 Python 2.7 和 3.4+ 的基于 Python 的安装脚本中,我想将一个目录添加到PATH环境变量中(如果还没有的话)。当脚本退出时,PATH应该包含新目录,用于当前的 Fish shell 会话以及未来的登录。

为了实现这一点,我可以想到两种可能的方法:

  1. 创建一个包含以下内容的localpath.fish文件~/.config/fish/conf.d/set PATH ~/.local/bin $PATH
  2. 使用 Pythonsubprocess运行:set -U fish_user_paths ~/.local/bin $fish_user_paths

我更喜欢后一种方法,但我尝试通过subprocess几种不同的方式调用 Fish,但都无济于事。例如:

>>> subprocess.check_output(["fish", "-c", "echo", "Hello", "World!"], shell=True)

在 Fish 3.0.2 和 Python 3.7.4 上,上述产生:

<W> fish: Current terminal parameters have rows and/or columns set to zero.
<W> fish: The stty command can be used to correct this (e.g., stty rows 80 columns 24).

…并且 Python REPL 提示不会重新出现。点击 CTRL-C 不会正确退出,导致 Python REPL 处于几乎不可用的状态,直到退出并重新启动。(这似乎是一个已知问题。)

同样,使用subprocess.run()Python 3.7 的capture_output参数无法产生预期的输出:

>>> subprocess.run(["fish", "-c", "echo", "Hello", "World!"], capture_output=True)
CompletedProcess(args=['fish', '-c', 'echo', 'Hello', 'World!'], returncode=0, stdout=b'\n', stderr=b'')

我的问题:

  1. 有比上述两种方法更好的策略吗?
  2. 如果使用第一种方法,我将如何PATH从 Python 脚本中调整当前的 Fish shell 会话?
  3. 如果使用该set -U fish_user_paths […]方法,从 Python 脚本中调用该方法的合适方法是什么?

标签: pythonshellsubprocessfish

解决方案


您走在正确的轨道上,但整个命令必须作为单个参数。此外,您不希望事先进行外壳扩展。

所以你可以写:

subprocess.check_output(["fish", "-c", "echo hello world"])

它会做你所期望的。对于 PATH 案例:

subprocess.check_output(["fish", "-c", "set -U fish_user_paths ~/.local/bin $fish_user_paths"])

这将修改父进程中的 $PATH 。


推荐阅读