Как установить переменную окружения только на время работы скрипта?

127

В Linux (Ubuntu 11.04) в bash можно ли временно установить переменную среды, которая будет отличаться от обычной переменной только на время выполнения сценария? Например, в сценарии оболочки создание переносимого приложения, сохраняющего в HOME, путем временной установки HOME в папку в текущем рабочем каталоге и последующего запуска приложения.

suchipi
источник
5
Было бы труднее, если бы вы хотели, чтобы настройка длилась дольше, чем время сценария
Nemo

Ответы:

120
VAR1=value1 VAR2=value2 myScript args ...
Rockallite
источник
2
Я сам делал это много раз, чтобы сбежать vblank_mode=0 glxgears. Он работает, но он также говорит vblank_mode=0: command not foundпосле запуска, тогда как добавление envэтого не вызывает. [тестирование ...] Очевидно, zsh это не нравится (но все еще правильно использует), но bash с этим справляется. Думаю, с этого момента я буду использовать этот envметод.
Chinoto Vokro
2
со скриптами работает, а как насчет VAR1="hello" echo $VAR1ничего не возвращает?
Zibri 07
2
@Zibri - это когда происходит расширение. Наверное, ты сможешь сделать что-то подобное:VAR1="hello" bash -c 'echo $VAR1'
cybergrind 01
Проголосовали за демонстрацию того, что это возможно даже для нескольких переменных среды.
Binarus
70
env VAR=value myScript args ...
Гленн Джекман
источник
18
ИлиVAR=value myScript args ...
Rockallite
9
1. Почему PATH=$PATH:XYZ echo $PATH | grep XYZнет вывода? 2. В чем разница между использованием и неиспользованием env?
qubodup
18
потому что оболочка расширяет переменную PATH перед выполнением команды echo. Вам нужно отложить это расширение. Один из способов: PATH=$PATH:XYZ sh -c 'echo $PATH' | grep XYZ- одинарные кавычки здесь являются ключевыми
Гленн Джекман
14
В чем разница между использованием envи неиспользованием?
Мохаммед Нурелдин
Похоже, что это не работает в IFS=$'\n' for l in lines; do ... done
одинарном лайнере
31

Просто положи

export HOME=/blah/whatever

в том месте сценария, где вы хотите, чтобы изменение произошло. Поскольку каждый процесс имеет свой собственный набор переменных среды, это определение автоматически теряет какое-либо значение при завершении сценария (а вместе с ним и экземпляра bash с измененным окружением).

хмахольм осталась над Моникой
источник
11
Это заблуждение. exportпередаст переменную подоболочкам, но не контролирует родительскую оболочку. Если вы пишете сценарий, который начинается с "#! / Bin / sh" или подобного, ЛЮБАЯ заданная вами переменная исчезнет при выходе из сценария.
brightlancer
1
@brightlancer, это правда, но, похоже, не противоречит всему, что я написал. (За исключением того, что сценарий может запускать фоновый процесс, но я думаю, что это выходит за рамки уровня сложности OP и только запутает).
hmakholm ушел из-за Моники
5
Экспорт не нужен. Кроме того, ваш ответ работает только в том случае, если его сценарий вызывает интерпретатор (#! / Bin / sh или тому подобное). Если его «сценарий» этого не сделает, то то, что вы ему только что сказали, сохранится и после окончания его сценария. Вот почему я сказал, что ваш ответ вводит в заблуждение - он может быть правильным, а может и нет, но в нем определенно есть ненужная и сбивающая с толку часть, потому что это может заставить кого-то подумать, что «экспорт» - это необходимый элемент, который он искал.
brightlancer
7
@brightlancer: экспорт необходим, если сценарий OP вызывает субскрипты, которые сами зависят от $ HOME, и я не осмелился предположить, что это не так. Кроме того, bash создаст подоболочку для запуска сценария, даже если сценарий не имеет строки shebang, а представляет собой просто текстовый файл с установленным битом выполнения. Попробуйте - присвоения переменных в скрипте не отображаются в оболочке, из которой вы его вызываете. Только если вы явно укажете sourceсценарий, он будет выполняться той же оболочкой, в которой вы вводите команду.
hmakholm ушел из-за Моники
4
@brightlancer: экспорт необходим, если он хочет $HOMEнаследовать любые команды, выполняемые из скрипта. А если он этого не сделает, и установка $HOMEтолько для пользы самого скрипта, тогда ему, вероятно, будет лучше изменить скрипт, чтобы он относился к чему-то другому, кроме $HOME.
Кейт Томпсон,