tee -a: Append While Showing Output
tee copies stdin to one or more files and to stdout; -a appends rather than overwriting.
tee lets a step both log to a file and keep printing to the console. -a is the difference between appending and clobbering.
What it does
tee reads stdin, writes it to each named file, and also passes it through to stdout. Without -a it truncates each file first; with -a it appends. You can name several files at once, and /dev/stderr to also send a copy to stderr.
Common usage
make build 2>&1 | tee build.log # show and save
echo "step done" | tee -a run.log # append a line
command | tee out.txt err.txt # write two files
command | tee /dev/stderr | process # log and keep pipingOptions
| Flag | What it does |
|---|---|
| -a | Append to files instead of truncating |
| file1 file2 ... | Write the stream to multiple files |
| /dev/stderr | Send a copy to stderr while piping stdout |
| -i | Ignore interrupt signals |
| -p | Diagnose write errors on non-pipe outputs |
In CI
cmd 2>&1 | tee build.log captures a step's combined output for the artifact log while still streaming it live. Note that tee becomes the last command in the pipeline, so $? is tee's exit code, not cmd's; use set -o pipefail or ${PIPESTATUS[0]} to catch the real failure.
Common errors in CI
A step "passes" even though the command failed because the pipeline exit status is tee's (success) not the command's; enable set -o pipefail. Without -a, tee truncates the log each run, losing earlier content; add -a to accumulate. Writing to a read-only path makes tee error per file; point logs at /tmp on locked-down runners.