Круглые скобки в bash — подоболочка против группировки

На справочной странице bash в разделе "составные команды ", есть следующие две записи:

(список) список выполняется в среде подоболочки (см. СРЕДА ВЫПОЛНЕНИЯ КОМАНД ниже). Присвоения переменных и встроенные команды, влияющие на среду оболочки, не остаются в силе после завершения команды. Статус возврата - это статус выхода из списка.

и в разделе test и [[:

(выражение) Возвращает значение выражения. Это может быть использовано для переопределения обычного приоритета операторов.

Единственная разница, которую я вижу, заключается в том, что в одном скобки не имеют пробелов рядом с ними, а в другом они есть. Это то, что на самом деле отличает группировку от подоболочки, или это зависит от контекста?

Другими словами, если я бегу

if ! [ 2 -eq 2 ] || ( [ 2 -eq 2 ] && [ 4 -eq 4 ] ); then echo "hello"; fi

это просто группировка условий или работа в подоболочке?


person Chris Middleton    schedule 25.03.2015    source источник
comment
Кстати, обратите внимание, что && имеет более высокий приоритет, чем ||, поэтому скобки в этом случае на самом деле не нужны.   -  person Tom Fenech    schedule 25.03.2015
comment
Если вы хотите группировать без подоболочки, используйте { list; } — перед закрывающей фигурной скобкой требуется точка с запятой или новая строка.   -  person glenn jackman    schedule 25.03.2015


Ответы (1)


Рассматриваемый контекст для этих записей имеет значение.

Последний находится в документации для конструкции [[ и документирует поведение этой конструкции в отношении ее аргументов.

В первом обсуждается конструкция составной команды оболочки верхнего уровня (например, сама конструкция [[) и вводится вложенная оболочка.

Это снова появляется в описании команды test/[ позже на странице руководства (но это, по сути, то же самое, что и обсуждение [[).

Чтобы выполнить группировку в текущей оболочке, вы можете использовать фигурные скобки:

if ! [ 2 -eq 2 ] || { [ 2 -eq 2 ] && [ 4 -eq 4 ]; }; then
    ...
fi

(Обратите внимание на пробелы внутри фигурных скобок и дополнительную точку с запятой, которые необходимы.)

person Etan Reisner    schedule 25.03.2015
comment
Последнее есть в документации к конструкции [[... Упс, не заметил. Итак, что происходит, когда я делаю if ... ( someexpr ), как указано выше, без использования [[? - person Chris Middleton; 25.03.2015
comment
if (somexpr); then echo something; fi это someexpr в подоболочке. - person Etan Reisner; 25.03.2015