Я изучаю сценарии оболочки с bash, и мне нужно знать разницу между (...)
и {...}
. Как выбрать между двумя при написании сценария?
Я изучаю сценарии оболочки с bash, и мне нужно знать разницу между (...)
и {...}
. Как выбрать между двумя при написании сценария?
Ответы:
Если вы хотите, чтобы побочные эффекты из списка команд влияли на вашу текущую оболочку, используйте {...}
Если вы хотите отменить любые побочные эффекты, используйте(...)
Например, я мог бы использовать подоболочку, если я:
$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
local
ключевого слова имеет большое значение для очистки этого загрязнения.
pwd; (count_tmp); pwd;
Из официальной документации bash :
()
( list )
Размещение списка команд в скобках приводит к созданию среды подоболочки, и каждая из команд в списке выполняется в этой подоболочке. Поскольку список выполняется в подоболочке, назначения переменных не остаются в силе после завершения подоболочки.
{}
{ list; }
Помещение списка команд в фигурные скобки приводит к тому, что список выполняется в текущем контексте оболочки. Никакая подоболочка не создана. Точка с запятой (или новая строка) следующий список обязателен.
Код в «{}» выполняется в текущем потоке / процессе / среде, и изменения сохраняются, если говорить более кратко, код выполняется в текущей области.
Код в '()' запускается внутри отдельного дочернего процесса bash, который сбрасывается после выполнения. Этот дочерний процесс часто называют вложенной оболочкой, и его можно рассматривать как новую дочернюю область.
В качестве примера рассмотрим следующее ...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
Обратите внимание, что в первом примере с «{}» переменная по-прежнему установлена даже после закрывающего «}», тогда как в примере с «()» переменная не установлена вне области действия «()».
(...)
используются для запуска кода в под-оболочке. Код, используемый ниже {...}
, не будет использоваться в под-оболочке.