From within a Python-based installation script running on Fish shell and supporting Python 2.7 and 3.4+, I want to add a directory to the PATH
environment variable if not already present. When the script exits, PATH
should contain the new directory, both for the current Fish shell session as well as future logins.
To achieve this, I can think of two potential approaches:
localpath.fish
file in ~/.config/fish/conf.d/
containing: set PATH ~/.local/bin $PATH
subprocess
to run: set -U fish_user_paths ~/.local/bin $fish_user_paths
I would prefer the latter approach, but I have tried invoking Fish via subprocess
several different ways, all to no avail. For example:
>>> subprocess.check_output(["fish", "-c", "echo", "Hello", "World!"], shell=True)
On Fish 3.0.2 and Python 3.7.4, the above yields:
<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).
… and the Python REPL prompt does not re-appear. Tapping CTRL-C does not exit properly, leaving the Python REPL in a mostly unusable state until quit and relaunched. (This appears to be a known issue.)
Similarly, using subprocess.run()
with Python 3.7’s capture_output
parameter fails to yield the expected 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'')
My questions:
PATH
for the current Fish shell session from within a Python script?set -U fish_user_paths […]
approach, what would be the appropriate way to invoke that from within a Python script?You're on the right track, but the whole command has to be as a single argument. Also you don't want shell expansion beforehand.
So you could write:
subprocess.check_output(["fish", "-c", "echo hello world"])
and it will do what you expect. For the PATH case:
subprocess.check_output(["fish", "-c", "set -U fish_user_paths ~/.local/bin $fish_user_paths"])
and this will modify $PATH in the parent process.