Глобальные переменные среды в сценарии оболочки

83

Как установить глобальную переменную среды в сценарии bash?

Если я сделаю что-то вроде

#!/bin/bash
FOO=bar

...или же

#!/bin/bash
export FOO=bar

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

Alex
источник

Ответы:

143

Запустите свой сценарий с помощью .

. myscript.sh

Это запустит сценарий в текущей среде оболочки.

export определяет, какие переменные будут доступны для новых процессов, поэтому, если вы скажете

FOO=1
export BAR=2
./runScript.sh

тогда $BARбудет доступен в среде runScript.sh, но $FOOне будет.

толпа
источник
27
Будьте осторожны с первым. Без косой черты он будет смотреться на вашем пути: используйте что-то вроде '. ./myscript.sh ', если вы хотите убедиться, что он запускает конкретный.
paxdiablo
13
sourceэто псевдоним для .. Так что вы можете бежать source myscript.shвместо этого, если хотите быть более откровенным.
Ehtesh Choudhury 01
Мне интересно, что происходит, когда я запускаю скрипт с точкой и пробелом. пример . myscript
cNgamba 09
54

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

. ./setfoo.sh

Это выполняет его в контексте текущей оболочки, а не как вспомогательную оболочку.

На странице руководства bash:

. имя файла [аргументы]
имя файла источника [аргументы]

Прочитать и выполнить команды из имени файла в текущей среде оболочки и вернуть статус выхода последней команды, выполненной из файла.

Если имя файла не содержит косой черты, имена файлов в PATH используются для поиска каталога, содержащего имя файла.

Файл, который ищется в PATH, не обязательно должен быть исполняемым. Когда bash не находится в режиме POSIX, выполняется поиск в текущем каталоге, если в PATH не найден файл.

Если параметр sourcepath для встроенной команды shopt отключен, поиск по PATH не выполняется.

Если предоставлены какие-либо аргументы, они становятся позиционными параметрами при выполнении filename.

В противном случае позиционные параметры не изменяются. Статус возврата - это статус последней команды, выполненной в рамках сценария (0, если никакие команды не выполняются), и false, если имя файла не найдено или не может быть прочитано.

Paxdiablo
источник
Интересно - я раньше не видел такого синтаксиса. Это эквивалент источника ./setfoo.sh?
ire_and_curses
2
То же самое, только быстрее набирать (и более совместимо с более старыми системами - в ksh нет исходной команды, но есть '.').
paxdiablo
9

source myscript.sh тоже возможно.

Описание команды linux source:

source is a Unix command that evaluates the file following the command, 
as a list of commands, executed in the current context
CDT
источник
Может быть, здесь чуть подробнее. Как насчет очень краткого описания того, что sourceделает?
Филлип Клауд
Введите @PhillipCloud man sourceв терминал, и вы получите то, что хотите.
CDT
5
Я знаком с source. Может быть, OP нет.
Филлип Клауд
2
@PhillipCloud Я сам хотел бы получить более подробную информацию. Если вы хотите отредактировать ответ, вы определенно можете это сделать. Помогите делу и все такое ... Спасибо!
Дэн Розенстарк
4
#!/bin/bash
export FOO=bar

или же

#!/bin/bash
FOO=bar
export FOO

человек экспорт:

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

Андрей Каиников
источник
Пожалуйста, каждому новичку в написании сценариев оболочки: обратите внимание, что между именем envvar, символом '=' и самим значением нет пробела; это не сработает:export FOO = /mydir/bar
russellhoff
-3
FOO=bar
export FOO
Нико
источник
2
Это не работает, это не устанавливает переменную среды для родительского процесса.
dreamlax
3
Только родительский процесс может устанавливать переменную среды для родительского процесса.
Гленн Джекман,