BudiBadu Logo
Samplebadu

Bash by Example: Stdin, Stdout, Stderr

Bash 5.0+

Deep dive into file descriptors 0, 1, and 2 representing stdin, stdout, and stderr, understanding how the operating system manages input and output streams, explicitly redirecting to specific file descriptors, creating custom file descriptors for logging and complex I/O patterns, and applying proper stream separation for robust script design.

Code

#!/bin/bash

# Printing to Stdout (FD 1) - Default
echo "This goes to standard output"

# Printing to Stderr (FD 2)
# We redirect echo's stdout to stderr
echo "This is an error message" >&2

# Reading from Stdin (FD 0)
echo "Enter your name:"
# read reads from FD 0 by default
read name
echo "Hello, $name"

# Custom File Descriptors (Advanced)
# Open FD 3 for writing to a file
exec 3> custom.log

echo "Log entry 1" >&3
echo "Log entry 2" >&3

# Close FD 3
exec 3>&-

echo "Check custom.log for entries."
cat custom.log
rm custom.log

Explanation

Understanding File Descriptors (FDs) is key to mastering Bash I/O. The operating system tracks open files using integers. 0 is input, 1 is output, and 2 is error. When you run ls | grep foo, the shell connects the FD 1 of ls to the FD 0 of grep.

You can explicitly write to stderr using >&2. This is best practice for error messages in scripts. If a user runs your script like ./script.sh > output.txt, they expect the output file to contain data, not error messages. By writing errors to FD 2, they will still appear on the screen (alerting the user) even when standard output is redirected to a file.

Bash also allows you to open your own file descriptors (3-9) using the exec command. This allows you to keep a file open for writing throughout the script's execution, rather than opening and closing it for every single line (>> file). This is more efficient and cleaner for heavy logging tasks.

Code Breakdown

8
>&2 redirects the output of this specific echo command to File Descriptor 2. Even if the script output is piped, this message will likely print to the terminal.
18
exec 3> file opens the file for writing and assigns it to FD 3. It stays open until the script ends or we close it.
24
exec 3>&- closes File Descriptor 3. The - indicates "close".