Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The | (pipe) is a control operator in Bash used to construct a pipeline. It facilitates unidirectional inter-process communication (IPC) by connecting the standard output (stdout, file descriptor 1) of a preceding command directly to the standard input (stdin, file descriptor 0) of the subsequent command.
command1 | command2 [ | command3 ... ]

Execution Mechanics

When Bash encounters a pipeline, it does not wait for the first command to finish before starting the second. Instead, it executes all commands in the pipeline concurrently. By default, each command in a pipeline is invoked within its own separate subshell environment. This means variable assignments or state changes made within any of the piped commands will not persist in the parent shell once the pipeline terminates. Under the hood, Bash implements this using the POSIX pipe() system call to create an anonymous data channel in the kernel. It then uses fork() to spawn the child processes and dup2() to map the file descriptors so that the write end of the pipe replaces command1’s stdout, and the read end replaces command2’s stdin.

Stream Handling

The standard | operator exclusively redirects file descriptor 1 (stdout). Standard error (stderr, file descriptor 2) is ignored by the pipe and will continue to output to the parent process’s default error stream (typically the terminal). To pipe both stdout and stderr simultaneously, Bash 4.0 introduced the |& operator, which acts as syntactic sugar for 2>&1 |.

# Pipes only stdout (fd 1)
command1 | command2


# Pipes both stdout (fd 1) and stderr (fd 2)
command1 |& command2

Exit Status Behavior

The exit status ($?) of a pipeline is determined strictly by the exit status of the last command in the chain. If command1 encounters a fatal error and returns 1, but command2 executes successfully and returns 0, the overall pipeline will return 0. To alter this behavior, Bash provides the pipefail shell option. When enabled, the pipeline’s return status becomes the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.

# Enforce strict exit status evaluation across the pipeline
set -o pipefail
Additionally, Bash populates the PIPESTATUS array variable after a pipeline executes. This array contains the individual exit status codes of every command in the most recently executed foreground pipeline, indexed from left to right. It is critical to note that the PIPESTATUS array is highly volatile; it is overwritten by the very next command executed by the shell. If a developer attempts to evaluate ${PIPESTATUS[0]} and then ${PIPESTATUS[1]} on sequential lines, the second check will fail because the first evaluation command (e.g., an if statement or echo) will have already overwritten the array. To preserve these exit codes, the array must be copied immediately after the pipeline executes.
command1 | command2 | command3


# Copy the array immediately to prevent it from being overwritten
codes=("${PIPESTATUS[@]}")


# ${codes[0]} contains the exit code of command1

# ${codes[1]} contains the exit code of command2

# ${codes[2]} contains the exit code of command3
Master Bash with Deep Grasping Methodology!Learn More