Как запустить программу в чистой среде в bash?

Ответы:

127

Вы можете сделать это с env:

env -i your_command

В отличие от комментариев ниже, это делает совершенно ясно из окружающей среды, но это не мешает your_commandустановить новые переменные. В частности, запуск оболочки вызовет /etc/profileзапуск, и оболочка может иметь также некоторые встроенные настройки.

Вы можете проверить это с:

env -i env

т.е. протрите окружающую среду и затем напечатайте это. Вывод будет пустым.

военно-картографическая служба
источник
4
Это не полностью очищает окружающую среду: echo 'echo $PATH' > test.sh && chmod u+x test.sh && env -i test.shпечатает /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin.
10
2
Тем не менее, кажется, что это самое близкое, что вы можете получить - похоже, что переменные, как PATH, PWDи SHLVLустанавливаются автоматически Bash. +1.
10
3
@ I0b0: см. Мое редактирование.
Амс
3
Переменная PATH в сценарии первого комментатора отсутствует в среде и, следовательно, не является переменной среды. Bash, по-видимому, устанавливает свою собственную обычную переменную оболочки, называемую PATH, если для нее не было экспортировано ни одной: env -i bash --norc -c "declare -p PATH"give declare -- PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.". Обратите внимание на «-x» для экспортируемой (и, следовательно, части среды), если вы экспортируете ее самостоятельно: env -i bash --norc -c "export PATH; declare -p PATH"givedeclare -x PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."
Binary Phile
34

«Чистая» bashсреда может иметь место с

$ env -i bash --noprofile --norc
  • Команда env -iвыполняет команду, переданную ей в командной строке, без передачи каких-либо экспортированных переменных среды старой среды оболочки в среду исполняемой программы.

  • Эта --noprofileопция останавливает bashчтение общесистемных или личных сценариев инициализации оболочки, которые в противном случае считывались бы для оболочки входа в систему.

  • Эта --norcопция останавливает bashчтение сценариев инициализации личной оболочки, которые в противном случае считывались бы для интерактивной оболочки.

Кусалананда
источник
Мой env не распознает эти опции.
Пауло Карвалью
@PauloCarvalho Ваша система не поддерживает env -i? На какой ты системе?
Кусалананда
Извините, это работает в оболочке. Я попытался поместить это в подлинник, и как-то это бросило ошибку.
Пауло Карвалью,
@PauloCarvalho Извините, я не вижу, какую команду вы ввели или какая у вас ошибка.
Кусалананда
Отлично - именно то, что я искал. envчтобы очистить мою среду, и --noprofileизбежать поиска / etc / profile и друзей, и --norcизбежать поиска ~ / .bashrc и друзей.
Фелипе Альварес
28

env -i somecommandзапускает команду в пустой среде, как уже упоминалось в ams .

Многие программы используют некоторые важные переменные среды, поэтому вы можете захотеть сохранить их:

env -i HOME="$HOME" LC_CTYPE="${LC_ALL:-${LC_CTYPE:-$LANG}}" PATH="$PATH" USER="$USER" somecommand

Кроме того, вы можете войти в небольшую среду входа в систему.

ssh localhost somecommand
жилль
источник
1
Работает при запуске команды на cmdline. Как я могу положить это в Shebang ?, не похоже на работу !
балки
Странно, но my envне поддерживает --разграничение и env -i FOO=bar -- envпопытки запуска команды с именем --.
Антак
@antak Это должно быть на env -i -- FOO=bar envсамом деле. Виноват. Не то, чтобы --это было полезно, поскольку то, что следует, не начинается с -.
Жиль
Не понимал, что ты всегда можешь зайти на локальный хост, это довольно странно. Какой там вариант использования.
Эдгар Арутюнян
@EdgarAroutiounian Вы можете использовать SSH для localhost, если он работает на SSH-сервере. Зачем программистам пытаться запретить это?
Жиль
4

Хотя принятый ответ правильный, обычно вы хотите:

env -i bash -l -c "printenv; and any other commands"

Это дает вам простой, но функциональный bash (такой же, какой вы получили бы при входе в неинтерактивный режим). Это, например, устанавливает язык, часовой пояс, HOME и т. Д.

Марчин Рачковски
источник
Это не совсем работает, потому что env -iочищает HOME, что означает, что bash -lвы не можете найти ваш .bash_profileи т. Д. Если вам нужна оболочка, похожая на ту, которую вы получили бы при новом входе в систему, вам нужно установить дополнительное косвенное указание в HOMEпервую очередь.
Эллиотт Слотер
Смотрите этот ответ: unix.stackexchange.com/a/451389/157340
Эллиот Слотер
1

Проблема с большинством ответов здесь в том, что она env -iочищается HOME, поэтому, даже если вы запустите bash -lее изнутри, она не будет читать ваши .bash_profileи т. Д. Если вы ищете оболочку, которая действует так, как будто вы только что сделали новый вход в систему, вы хотел бы вместо этого:

env -i HOME="$HOME" bash -l -c 'your_command'

Пример:

$ export ABC=123
$ env -i HOME="$HOME" bash -l -c 'env' | grep ABC
$ env HOME="$HOME" bash -l -c 'env' | grep ABC
ABC=123
Эллиот Слотер
источник
1
Обратите внимание, что bashбудет запущена оболочка входа .bash_loginили .bash_profile. Чтобы получить чистую среду, используйте --noprofileили установите HOMEкаталог, в котором нет этих файлов. Я полагаю, это зависит от того, что вы подразумеваете под «чистым».
Кусалананда
1
Да, если вам нужна оболочка, в которой буквально ничего нет, просто следуйте оригинальному ответу и делайте env -i bash -c .... Этот ответ специально для случаев, когда вам нужна оболочка, которая выглядит так, как будто вы только что сделали новый вход в систему на компьютере.
Эллиотт Слотер
0

Чтобы ответить на комментарий Балки (и отвечая на мой собственный вопрос в процессе :-):

% echo Environment in calling shell: vars: $(env |wc -l); echo; ./du; echo; cat du
Environment in calling shell: vars: 43

==> This is the environment: vars: 5
PATH="$PATH"
PWD=/Users/nick
SHLVL=1
SOMETHING_TO_KEEP="$USER"
_=/usr/bin/env
==> The end.

#!/usr/bin/env -i SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh

echo "==> This is the environment: vars:" $(/usr/bin/env | /usr/bin/wc -l)
/usr/bin/env
echo "==> The end."
Coroos
источник
Когда я пытаюсь сделать это в своей строке shebang в CentOS 7.6, я получаю эту ошибку от env:/usr/bin/env: invalid option -- ' ' Try '/usr/bin/env --help' for more information.
ScottJ
Если я изменю сценарий на длинный аргумент, --ignore-environmentя получу следующее:/usr/bin/env: unrecognized option '--ignore-environment SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh' Try '/usr/bin/env --help' for more information.
ScottJ