Я увидел выражение 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
.