Я можу запустити ENV_VAR=value commandбіг commandіз конкретним значенням для ENV_VAR. Що еквівалентно дезактивувати ENV_VARдля command?
cmdдля цього.
Я можу запустити ENV_VAR=value commandбіг commandіз конкретним значенням для ENV_VAR. Що еквівалентно дезактивувати ENV_VARдля command?
cmdдля цього.
Відповіді:
Крім -iопції, яка стирає все середовище, POSIX envне дає жодного способу скинути змінну.
Однак, маючи кілька envреалізацій (включаючи busyboxпринаймні GNU, 'та FreeBSD), ви можете:
env -u ENV_VAR command
Що буде працювати при видаленні кожного екземпляра ENV_VARзмінної із середовища (зауважте, що вона не працює для змінної середовища з порожнім іменем ( env -u ''або дає помилку, або неефективна залежно від реалізації, хоча всі приймають env '=value', ймовірно, обмеження) виникає функцією unsetenv()C, якій POSIX вимагає повернути помилку для порожнього рядка, тоді як для цього немає обмеження putenv())).
Портативно (в оболонках POSIX) ви можете:
(unset -v ENV_VAR; exec command)
(зауважте, що з деякими оболонками, використовуючи execможе змінювати commandзапускається: запускає файлову систему замість функції або вбудований, наприклад, (і, очевидно, обійде aliasрозширення), як envвище. Ви хочете опустити це в цих випадках) .
Але це не буде працювати для змінних оточення, які мають ім'я, яке не можна приєднати до змінної оболонки (зауважте, що деякі оболонки, як-от як mkshби знімали ці змінні з оточення при запуску), або змінні, позначені лише для читання.
-vпризначений для оболонки Bourne, і без bashякої unsetне -vможна було б скинути ENV_VAR функцію, якби не було змінної за цією назвою. Більшість інших оболонок не скасує функції, якщо ви не передасте цей -fпараметр. (навряд чи змінить практику).
(Також остерігайтеся про помилку / помилковою особливості з bash/ mksh/ yashякого unset, при деяких обставини не можуть скинути змінні, але показують змінний у зовнішній області видимості )
Якщо perlє, ви можете зробити:
perl -e 'delete $ENV{shift@ARGV}; exec @ARGV or die$!' ENV_VAR command
Що буде працювати навіть для змінної середовища з порожнім ім'ям.
Тепер усі вони не працюватимуть, якщо ви хочете змінити змінну середовища для вбудованої або функції та не хочете, щоб вони працювали в підкашлі, як-от у bash:
env -u LANG printf -v var %.3f 1.2 # would run /usr/bin/printf instead
(unset -v LANG; printf -v var %.3f 1.2) # changes to $var lost afterwards
(тут вимкнення LANG як помилкового підходу при переконуванні .використовується і розуміється як десятковий роздільник. Було б краще використовувати LC_ALL=C printf...для цього)
За допомогою деяких оболонок ви можете замість цього створити локальну область для змінної за допомогою функції:
without() {
local "$1" # $1 variable declared as initially unset in bash¹
shift
"$@"
}
without LANG printf -v var %.3f 1.2
З zsh, ви також можете використовувати анонімну функцію:
(){local ENV_VAR; command}
Такий підхід не буде працювати в деяких оболонках (як, наприклад, на основі оболонки Almquist), localякі не оголошують змінну як початкову не встановлену (але успадковують значення та атрибути). У цих випадках ви можете це робити local ENV_VAR; unset ENV_VAR, але не робіть цього в mkshабо yash( typesetзамість localцього), оскільки це не спрацювало б, це unsetбуло б лише скасуванням local.
¹ Також майте на увазі bash, що локальний ENV_VAR(навіть не встановлений) збереже експортний атрибут. Отже, якби commandбула функція, якій присвоюється значення ENV_VAR, змінна була б доступна в оточенні команд, викликаних згодом. unset ENV_VARзрозумів би цей атрибут. Або ви можете використовувати, local +x ENV_VARщо також забезпечить чистий діапазон (якщо тільки ця змінна не була оголошена лише для читання, але тоді ви нічого не можете з цим зробити bash).
env '=foo' python -c 'import os; print os.environ[""]'. Я не думаю, що багато людей захочуть встановити подібну змінну.
Наскільки я не знаю прямого еквівалента; ви можете скористатися передплатою:
(unset ENV_VAR; exec command)
(unset ENV_VAR; exec somecommand)якщо ви хочете бути еквівалентними оригіналу за ефективністю (споживши нижню частину корпусу). Як це є, це додає додаткову вилку.
commandє останньою командою в виклику додаткової оболонки .
env -u.
Можна використовувати ENV_VAR= command
Це насправді не скидає змінну, але вона може бути корисною у багатьох випадках (сценарії оболонки зазвичай просто використовують, test -nщоб перевірити, чи встановлена змінна):
$ export ENV_VAR=foo
$ mycommand
ENV_VAR: foo
$ ENV_VAR=bar mycommand
ENV_VAR: bar
$ ENV_VAR= mycommand
ENV_VAR:
commandце невдалий вибір заповнювачів, оскільки насправді є вбудована команда під цим іменем.mycommandабоsomecommandабо таке може бути кращою звичкою заходити.