Установка $PATH через команду с tox

В настоящее время используется tox для тестирования пакета Python и используется библиотека Python (chromedriver-binary) для установки chromedriver.

Эта библиотека создает скрипт (chromedriver-path), который при вызове выводит PATH, где установлен chromedriver. Обычный способ использовать это - запустить:

export PATH=$PATH:`chromedriver-path`

Я безуспешно пробовал следующее в tox.ini

setenv= 
  PATH = {env:PATH}{:}`chromedriver-path`

Эти ошибки, как и ожидалось:

FileNotFoundError: [Errno 2] Нет такого файла или каталога: 'chromedriver': 'chromedriver'

Подразумевается, что команда setenv никогда не вызывается/не запускается.

commands=
  export PATH=$PATH:`chromedriver-path

Это не удается с:

ОШИБКА: InvocationError для команды не удалось найти исполняемый экспорт

Как мне заставить это работать?


person match    schedule 13.04.2019    source источник
comment
Команды выполняются в подпроцессах. Подпроцессы не могут изменить среду своих родителей.   -  person Charles Duffy    schedule 13.04.2019
comment
Можете ли вы иметь выходные данные chromedriver-path в среде (под любым именем) до запуска tox вообще? Если вы поместите export chromedriver_path="$(chromedriver-path)" в свой .bash_profile (или аналогичный, соответствующий платформе и т. д., чтобы он был экспортирован до запуска tox), вы сможете указать {env:PATH}{:}{env:chromedriver_path} в своем tox.ini, предполагая, что синтаксис, который вы указали, был правильным.   -  person Charles Duffy    schedule 13.04.2019
comment
Сценарий создается с помощью pip установки chromedriver-binary через tox deps, поэтому он не существует до запуска tox.   -  person match    schedule 13.04.2019
comment
Будет ли работать команда bash в commands? то есть что-то вроде bash -c 'PATH=$PATH:`chromedriver-path` py,test ...'   -  person match    schedule 13.04.2019
comment
Конечно, это может сработать. Я бы выбрал bash -c 'PATH=$PATH:$(chromedrive-path); exec "$@"' _ py test ..., предполагая, что в противном случае вы бы использовали py test .... (Предостережение: я знаю bash и Python, но не Tox; тем не менее, пункт выше заключается в том, что вы хотите, чтобы динамические компоненты не участвовали в аргументе, который непосредственно следует за -c, в максимально возможной степени, чтобы избежать атак с внедрением оболочки и других гадостей).   -  person Charles Duffy    schedule 13.04.2019
comment
(обратные кавычки в оболочке — это дурной тон — они плохо вложены друг в друга, они изменяют поведение обратных косых черт, и они не требовались буквально десятилетиями — синтаксис $(...) был стандартизирован с момента публикации POSIX.2 в 1992 году) .   -  person Charles Duffy    schedule 13.04.2019
comment
Запускаю его прямо сейчас - если это удастся, я дам вам знать, и вы можете написать ответ, который я приму. (и да, $() — это хорошо — я думал, что это ${}, и боялся, что tox его схватит!)   -  person match    schedule 13.04.2019
comment
Да, вроде работает - спасибо!   -  person match    schedule 13.04.2019


Ответы (1)


Команды не могут изменять переменные среды своих родительских процессов и, следовательно, не могут изменять переменные среды последующих команд, запускаемых путем разветвления этого родителя; они могут устанавливать переменные среды только для себя или своих детей.

Если бы вы смогли собрать выходные данные chromedriver-path до запуска tox, это было бы спорным вопросом. Если он доступен только в среде, которую создает сам токсин, все становится немного интереснее.

Один подход, который вы можете использовать, заключается в том, чтобы обернуть команды, которым нужна эта запись пути, в оболочку, которая ее добавляет. Рассмотрите возможность изменения:

commands=
  py test ...

to:

commands=
  sh -c 'PATH=$PATH:$(chromedrive-path); exec "$@"' _ py test ...
person Charles Duffy    schedule 13.04.2019