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 <(...) operator, known as process substitution, dynamically executes a command and exposes its standard output (stdout) as a temporary file path to an enclosing command. It bridges the gap between commands that strictly require file paths as arguments and commands that generate output to stdout.
outer_command <(inner_command)
Note: There must be no space between the < and the (. A space would cause Bash to interpret the < as a standard input redirection operator.

Execution Mechanism

When the Bash parser encounters the <(...) construct, it does not pass the literal string or the direct output to the outer command. Instead, it performs the following sequence of system-level operations:
  1. Descriptor Allocation: Bash creates a named pipe (FIFO) or allocates an anonymous pipe mapped to a file descriptor. On modern POSIX systems, this is typically exposed via the /dev/fd/ directory (e.g., /dev/fd/63).
  2. Asynchronous Execution: The inner_command is spawned in a background subshell.
  3. Stream Redirection: The stdout of the inner_command is connected to the write end of the allocated pipe or file descriptor.
  4. Argument Substitution: Bash replaces the entire <(...) syntax in the original command line with the absolute path to the read end of the pipe.
  5. Cleanup: Once the file descriptors are closed and the outer command terminates, Bash reaps the background process and destroys the temporary file descriptor or FIFO.

Visualizing the Substitution

Because Bash replaces the operator with a file path before the outer command executes, passing it to a command like echo reveals the underlying file descriptor rather than the output of the inner command:
$ echo <(ls)
/dev/fd/63
In this execution context, the outer command receives /dev/fd/63 as a standard positional argument. It opens this path as a file and reads the stream generated by the inner command.

Technical Characteristics

  • Concurrency: The inner process and the outer process run asynchronously. The outer command begins execution immediately, reading from the pipe as the inner command writes to it.
  • Unidirectional Stream: The <(...) variant is strictly for reading output from the inner command. It is a read-only stream from the perspective of the outer command.
  • Non-Seekable: Because the underlying mechanism relies on pipes or FIFOs, the resulting “file” is a continuous stream. The outer command cannot perform seek operations (e.g., lseek(), rewinding, or jumping to specific byte offsets) on the provided file path.
  • Scope: The file descriptor is transient and strictly scoped to the execution lifecycle of the outer command.
Master Bash with Deep Grasping Methodology!Learn More