Как добавить каталог в PATH в оболочке Fish с помощью скрипта Python? - PullRequest
0 голосов
/ 01 ноября 2019

В скрипте установки на основе Python, работающем в оболочке Fish и поддерживающем Python 2.7 и 3.4+, я хочу добавить каталог в переменную среды PATH, если она еще не существует. Когда скрипт завершается, PATH должен содержать новый каталог, как для текущего сеанса оболочки Shell, так и для будущих входов в систему.

Чтобы достичь этого, я могу представить два возможных подхода:

  1. Создайте localpath.fish файл в ~/.config/fish/conf.d/, содержащий: set PATH ~/.local/bin $PATH
  2. Используйте Python's subprocess для запуска: set -U fish_user_paths ~/.local/bin $fish_user_paths

Я бы предпочел последнееподход, но я попытался вызвать Fish через subprocess несколькими различными способами, но все безрезультатно. Например:

>>> 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() с параметром capture_output в Python 3.7 не приводит к ожидаемому результату:

>>> 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 для текущегоСеанс Fish в скрипте Python?
  3. Если использовать подход set -U fish_user_paths […], какой будет подходящий способ вызвать его из скрипта Python?

1 Ответ

1 голос
/ 01 ноября 2019

Вы на правильном пути, но вся команда должна быть как один аргумент. Кроме того, вам не нужно заранее расширять оболочку.

Таким образом, вы можете написать:

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 в родительском процессе.

...