Я изучаю shell-скрипты с bash, и мне нужно знать разницу между (...)
и {...}
. Как выбрать между ними при написании сценария?
Я изучаю shell-скрипты с bash, и мне нужно знать разницу между (...)
и {...}
. Как выбрать между ними при написании сценария?
Если вы хотите, чтобы побочные эффекты списка команд влияли на вашу текущую оболочку, используйте {...}
Если вы хотите отказаться от каких-либо побочных эффектов, используйте (...)
Например, я мог бы использовать подоболочку, если I:
$IFS
для нескольких команд, но я не хочу изменять $IFS
глобально для текущей оболочки cd
где-то, но я не хочу менять $PWD
для текущей оболочки Стоит отметить, что круглые скобки могут использоваться в определении функции:
нормальное использование: привязки: тело функции выполняется в текущей оболочке; побочные эффекты остаются после завершения функции
$ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
$ pwd; count_tmp; pwd
/home/jackman
11
/tmp
$ echo "${#files[@]}"
11
необычное использование: круглые скобки: тело функции выполняется в подоболочке; побочные эффекты исчезают, когда подоболочка выходит из
$ cd ; unset files
$ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
$ pwd; count_tmp; pwd
/home/jackman
11
/home/jackman
$ echo "${#files[@]}"
0
Из официальной документации по bash :
() р>
( list )
Размещение списка команд между скобками приводит к созданию среды подклассов, и каждая из команд в списке должна выполняться в этой подоболочке. Поскольку список выполняется в подоболочке, присваивания переменных не остаются в силе после завершения подоболочки.
{} р>
{ list; }
Размещение списка команд между фигурными скобками приводит к тому, что список будет выполнен в текущем контексте оболочки. Не создается подоболочка. Требуется список с запятой (или новой строкой).
Код в '{}' выполняется в текущем потоке / процессе / среде, и изменения сохраняются, чтобы сделать его более кратким, код запускается в текущей области.
Код в '()' запускается внутри отдельного дочернего процесса bash, который отбрасывается после выполнения. Этот детский процесс часто называют
sub-shell и может рассматриваться как новый, подобный ребенку объем.
В качестве примера рассмотрим следующее ...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
Обратите внимание, что в первом примере с '{}' переменная по-прежнему установлена даже после закрытия '}', тогда как в примере с '() переменная не задана за пределами области' () '. Р>
(...)
используются для запуска кода в под-оболочке. Использованный код bewteen {...}
не будет использоваться в под-оболочке.