Яка різниця між командою
$ env FOO=bar baz
і
$ FOO=bar baz
Який ефект envмає?
Яка різниця між командою
$ env FOO=bar baz
і
$ FOO=bar baz
Який ефект envмає?
Відповіді:
Вони функціонально рівноцінні.
Основна відмінність полягає в тому, що env FOO=bar bazпередбачає виклик посередницького процесу між оболонкою та baz, де, як із FOO=bar bazоболонкою, безпосередньо викликається baz.
Тому в цьому плані FOO=bar bazє кращим.
Єдині ситуації, в яких я можу себе використовувати, env FOO=bar- це коли я повинен передати команду іншій команді.
Як конкретний приклад, скажімо, що у мене є скрипт для обгортки, який виконує деякі зміни середовища, а потім викликає execкоманду, передану йому, наприклад:
#!/bin/bash
FOO=bob
some stuff
exec "$@"
Якщо ви виконаєте це як myscript FOO=bar baz, execзаповіт видасть помилку як exec FOO=bar bazнедійсну.
Натомість ви називаєте це тим, myscript env FOO=bar bazщо виконується як exec env FOO=bar baz, і цілком дійсне.
FOO=bar exec bazхоча вам не потрібно envв останній точці.
execщось, чи використовує це ваше поточне оточення?
sudo FOO=bar bazможете передавати змінні середовища без необхідності env.
FOO=barсценарій. Якщо FOOце не завжди bar, я не хочу жорстко кодувати його, а замість цього передати його.
exec, наприклад FOO=bar exec baz.
У цьому конкретному прикладі немає ефективної різниці, якщо припустити, що ваша оболонка є оболонкою, сумісною з POSIX, і припустимо baz, що це виконуваний файл, а не вбудований оболонку.
Якщо ваша оболонка не є сумісною з POSIX оболонкою, наприклад, cshабо tcshсинтаксисом
FOO=bar baz
не працює, і немає еквівалентного синтаксису оболонки. Для цих оболонок envкоманда - єдиний спосіб переосмислити або ввести змінні середовища для однієї команди.
Якщо bazвбудована оболонка, скажімо, fcнаприклад, тоді envвона не дасть однакових результатів, оскільки envвиконує новий процес замість того, щоб запускати безпосередньо командну оболонку. Крім того, немає fcвиконуваного файлу, він може працювати тільки як вбудована команда , тому що , як вона взаємодіє з навколишнім середовищем оболонки, і так envбуде ніколи працювати з вбудованою командою , як fc.
Крім того, envпропонується -iопція, яка дозволяє запускати команду в порожньому середовищі лише із заданим набором змінних середовища. Так envможе бути дуже корисно, наприклад, для запуску процесів у санітарних умовах
env -i HOME=/tmp/homedir "PATH=`getconf PATH`" "TERM=$TERM" FOO=bar baz
tcshя писав би, (setenv FOO bar; baz)щоб отримати еквівалентну функцію.
Крім того, що вже було сказано
VAR=value cmd args > redirs
будучи функцією оболонки (Bourne / POSIX), ви обмежені в назві змінних оточуючих середовищ, до яких ви переходите cmd. Вони повинні бути дійсними назвами змінних оболонок і не повинні бути лише читаннями або спеціальними змінними оболонки.
Наприклад, ви не можете робити:
1=foo cmd
Або
+++=bar cmd
bash не дозволяє:
SHELLOPTS=xtrace cmd
Хоча ви можете:
env 1=foo cmd
env +++=bar cmd
env '=baz' cmd
(не те, що ви хочете чи не хочете це робити). Або:
env SHELLOPTS=xtrace cmd
(Мені іноді потрібно це робити).
Зауважте, що з envвами все ще не можна передавати рядок змінної середовища, яка не містить =(не те, що ви хотіли б зробити так).
Одне використання env- дозволити $PATHпошук виконуваних файлів у рядках shebang (тому що envвраховується $PATHпри пошуку виконуваного файлу). Це корисно, якщо виконуваний файл, який ви хочете викликати, може знаходитися в різних місцях на різних машинах. Наприклад,
#!/usr/bin/env perl
у першому рядку сценарію з набором виконуваних бітів буде виконуватися цей скрипт за допомогою Perl, незалежно від того, встановлений він у, /usr/bin/perlабо в ньому, /usr/local/bin/perlабо в зовсім іншому місці, доки каталог буде в шляху.
Звичайно, пошук шляхів пошуку має додатковий ризик, але тоді ризик не більший, ніж якби ви прямо написали perl yourscript.pl, що також шукає перл на шляху пошуку.
Інший час, коли envце справді корисно, якщо ви хочете повністю контролювати навколишнє середовище. Я запускаю серверну програму (Informix, якщо ви не можете здогадатися), чиє середовище я хочу повністю контролювати. Я запускаю його, використовуючи envв кінці скрипту, який встановлює купу змінних правильних значень:
env -i HOME="$IXD" \
INFORMIXDIR="$IXD" \
INFORMIXSERVER="$IXS" \
${IXC:+INFORMIXCONCSMCFG="$IXC"} \
${IXH:+INFORMIXSQLHOSTS="$IXH"} \
IFX_LISTEN_TIMEOUT=3 \
ONCONFIG="onconfig.$IXS" \
PATH="/bin:/usr/bin:$IXD/bin" \
SHELL=/bin/ksh \
TZ=UTC0 \
$ONINIT "$@"
-iВаріант існуючої хоче подарувати Петербург навколишнього середовища. Наступні VAR=valueпараметри встановлюють змінні середовища, які я хочу встановити; ім'я програми вводиться $ONINIT, і будь-які аргументи командного рядка передаються дослівно з "$@".
${IXH:+INFORMIXSQLHOSTS="$IXH"}Конструкція проходить тільки INFORMIXSQLHOSTS="$IXH"в envразі $IXHвстановлюється в непорожнє значення.