Kiet Nguyen logo
NotesNotesResumeResume
© 2026 Kiet Nguyen
← All categories

17

Redirection & Shell Glue

  • stdout/stderr to file
  • Pipe stages
  • Exit codes and && / ||
redirectionlistsexit statusteexargsquotingbuiltins

Must-know cold

  • cmd > file (overwrite stdout) · cmd >> file (append)
  • cmd 2> file (stderr) · cmd > file 2>&1 (both; order matters)
  • cmd1 | cmd2 · cmd1 && cmd2 · cmd1 || cmd2
  • echo $? · exit 0 = success
  • cmd 2>&1 | tee log.txt

File descriptors

Definition: Integer handles for open I/O streams (0 stdin, 1 stdout, 2 stderr).

FDNameDefault
0stdinterminal (interactive)
1stdoutterminal
2stderrterminal

Operators & builtins

redirection

Definition: Send command stdin/stdout/stderr to files or other descriptors.

OperatorArgumentMeaningExample
>FILEstdout overwrite (create/truncate)echo hi > out.txt
>>FILEstdout appendecho hi >> out.txt
2>FILEstderr overwritecmd 2> err.txt
2>>FILEstderr appendcmd 2>> err.txt
2>&1—Point stderr to wherever stdout currently goescmd >all.txt 2>&1
&>FILEBoth stdout+stderr to FILE (bash)cmd &> all.txt
&>>FILEAppend both (bash)cmd &>> all.txt
>/dev/nullDiscard stdoutcmd >/dev/null
2>/dev/nullDiscard stderrcmd 2>/dev/null
>/dev/null 2>&1Discard bothcmd >/dev/null 2>&1
<FILEstdin from FILEcmd < input.txt
<<WORDHeredoc until WORDcat <<EOF ... EOF
<<'WORD'—Heredoc; no expansioncat <<'EOF'
<<<STRINGHerestring as stdin (bash, not POSIX sh)grep x <<< "$var"
>&2—Write stdout to stderr (1>&2)echo err >&2
|—Pipe stdout only to next stdingrep E log | wc -l
|&—Pipe stdout+stderr (bash 4+; same as 2>&1 |)cmd |& tee all

Critical order rule

FormResult
cmd >file 2>&1stdout→file, then stderr copies that (file) — both in file
cmd 2>&1 >filestderr copies stdout first (still the terminal), then stdout→file — stderr stays on the terminal

Recipes

ComboMeaningExample
cmd >out.txt 2>&1Classic both streams
cmd >>out.txt 2>&1Append bothCron jobs
cmd 2>/dev/nullHide errorsCareful — can hide real failures
cmd >out.txt 2>err.txtSplit streams

lists

Definition: Chain commands by success, failure, or unconditional sequence.

OperatorArgumentMeaningExample
&&—Run right only if left exit 0mkdir d && cd d
||—Run right only if left non-zerogrep -q E f || echo none
;—Run sequentially regardlesscmd1; cmd2
&—Background left commandlongjob &
!cmdNegate exit statusif ! cmd; then ...

Flag combos

ComboMeaningExample
sudo apt update && sudo apt install -y xStop if update fails
cmd || trueForce success (mask failure — use carefully)
set -e in scriptsExit on a failing simple command (see caveats)Script safety

exit status

Definition: The numeric code of the last command ($?); 0 means success.

ItemArgumentMeaningExample
$?—Exit code of last commandecho $?
exitNExit shell/script with code Nexit 1
true—Always 0
false—Always non-zero
set -e—Exit on a failing simple command; not in if, ||, && (except last), !Top of bash scripts
set -u—Error on unset variables
set -o pipefail—Pipeline status is the last non-zero stage (others still run)Important

Convention: 0 = success · non-zero = failure (often 1; 127 = command not found)

Flag combos

ComboMeaningExample
cmd; echo $?Inspect status
set -euo pipefailStrict script modeProduction scripts

tee

Definition: Copy stdin to a file and still pass it through to stdout.

OptionArgumentMeaningExample
(none)FILECopy stdin to FILE and stdoutcmd | tee out.txt
-aFILEAppend to FILEcmd | tee -a out.txt
-i—Ignore SIGINTRare
multipleF1 F2Write multiple filescmd | tee a.txt b.txt

Flag combos

ComboMeaningExample
cmd 2>&1 | tee log.txtCapture both streams while watchingInstall logs
cmd | tee -a history.logAppend audit trail

xargs

Definition: Build and run command lines from stdin items (batch arguments).

OptionArgumentMeaningExample
(none)CMDBuild args from stdin words (whitespace; also honors quotes)echo a b | xargs ls
-nNMax N args per commandxargs -n 1 echo
-I{}Replace string with each linexargs -I{} cp {} /bak/
-PNParallel N processesxargs -P 4 -n 1 cmd
-0—NUL-delimited input (safe spaces)With find -print0
-dDELIMInput delimiter (GNU xargs)xargs -d '\n'
-r—Don’t run if empty input (GNU; BSD xargs already skips)xargs -r rm
-t—Print command before runDebug
-p—Prompt before eachInteractive

Flag combos

ComboMeaningExample
find . -name '*.log' -print0 | xargs -0 -r rmSafe delete by findSpaces; -r avoids GNU rm with no args
find . -name '*.txt' -print0 | xargs -0 grep -l ERRORGrep many files
cat hosts | xargs -n 1 -P 4 ping -c 1Parallel pingCareful load

quoting

Definition: Control how the shell expands variables, globs, and spaces.

FormMeaningExample
'single'Literal; no $, `, or $(...)grep '$foo' f
"double"Expand $var, $(...), and backticksecho "$HOME"
\Escape next charecho \$HOME
$var vs "$var"Unquoted splits on IFS whitespaceAlways quote paths

builtins

Definition: Shell built-ins. env, basename, and dirname are external utilities (/usr/bin/...), listed last.

CommandArgumentMeaningExample
echoSTRPrint (builtin; flags differ from /bin/echo)echo hello
printfFMT ARGSFormatted printprintf '%s\n' "$x"
readVARRead line into VARread -r line
exportVAR=valExport env to childrenexport PATH=...
command -vNAMEPath of command (builtin)command -v nginx
typeNAMEHow shell resolves nametype ls
env—Print environment (not a builtin)env | sort
env -iCMDEmpty env then CMDCron-like simulation
basenamePATHFinal component (external)basename /a/b
dirnamePATHParent path (external)dirname /a/b

Common recipes

GoalCommand
Save outputcmd > out.txt
Save output + errorscmd > out.txt 2>&1
Append logcmd >> app.log 2>&1
Watch + savecmd 2>&1 | tee build.log
Hide noisecmd 2>/dev/null
Pipeline countgrep ERROR app.log | wc -l
Fail-fast chaincmd1 && cmd2 && cmd3
Fallbackcmd || echo 'failed'
Exit codecmd; echo $?
Safe find deletefind . -name '*.tmp' -print0 | xargs -0 -r rm -f
Cron-like env testenv -i HOME="$HOME" PATH=/usr/bin:/bin /path/job.sh

Pitfalls

  • 2>&1 order with > — wrong order loses stderr.
  • Unquoted $var breaks on spaces — quote "$var".
  • Pipelines: without set -o pipefail, only the last command’s status counts. pipefail changes the status; it does not stop later stages.
  • cmd > file truncates the file before cmd runs — don’t use the same file as input naively.
  • xargs default splits on whitespace — use -0 with find -print0.
  • Masking failures with || true hides CI-visible errors.

For more details, try man <command> in your terminal.

Previous16 SSH & Remote Transfer