Что именно происходит, когда за трубой следует группа команд?

Что именно происходит, когда за трубой следует группа команд?

Я увидел выражение command1 | {command2;command3;command4}и задумался, что оно на самом деле означает. Я знаю символ вертикальной черты, я знаю, что он {...}заставляет выполнять команды внутри фигурных скобок в основной оболочке, но я озадачен тем, что они означают в сочетании.

решение1

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

Сценарий

command2
command3
command4

... которыйгрубоэто то, что { command2; command3; command4; }транслируется в (не принимая во внимание, что { ...; }номинально означает, что команды не выполняются в подоболочке), дается ввод от выполнения

command1

В зависимости от того, что делают эти три команды в первом скрипте, одна или несколько из них, скорее всего, будут использовать входные данные из command1, и если одна или несколько из них производят какие-либо выходные данные, они будут переданы в следующую часть конвейера, или на терминал, или туда, куда перенаправляется выходные данные конвейера.

решение2

{...}заставляет запускать команды внутри фигурных скобок в основной оболочке

Это не очень хорошее описание того, что делают фигурные скобки в целом. Фигурные скобки группируют команды таким образом, что не создают подоболочку. Другими словами, фигурные скобки сами по себе не создают подоболочку: код в фигурных скобках выполняется в той же оболочке, как если бы фигурных скобок не было, в отличие от кода в скобках, который всегда выполняется в подоболочке (поэтому его перенаправления, переменные и т. д. не влияют на родительскую оболочку или любую другую оболочку).

Цель фигурных скобок — разрешить написание сложных команд, где синтаксис ожидает одну команду. Например, в command1 | { command2; command3; command4; }(обратите внимание, что пробелы и точка с запятой в конце обязательны) правая часть конвейера — { command2; command3; command4; }. Команда { command2; command3; command4; }выполняет command2, затем command3, затем command4. Все эти команды получают входные данные из конвейера. (Поскольку команды выполняются последовательно, command3получает все входные данные, оставшиеся после command2выполнения, и т. д.)

решение3

Представьте себе фигурные скобки как безымянную функцию. Например:

command234 () { command2; command3; command4; }

command1 | command234 

дает тот же результат. когда все становится слишком сложным, я предпочитаю давать группам имена. хотя бы для тестирования.

решение4

Стандартный вывод command1будет использоваться для первой команды в блоке команд, которая начинает чтение из стандартного ввода. В большинстве случаев это будет command2.

Связанный контент