Q1In printf '%s\t%s\n' a b, what do \t and \n mean?
Output and Reports — Writing Files with printf and here-doc
This article is part of the Linux Course, where you master practical Linux skills from scratch, from basic commands through to shell scripting.
Align columns with printf '%s\t%s\n', append results with > and >>, split errors off with 2>, and embed $(wc -l) in a here-doc template to build a summary report — illustrated and practiced in a browser terminal.
Formatting your output — printf and routing where it goes
To print a script's results readably, pick between echo, which prints a string as-is, and printf, which takes a format and lines up widths and separators.
If you just want a variable's value on one line, echo "$v" is enough.
Write printf '%s\t%s\n' name age and the arguments go into the %s slots in order, \t becomes a tab and \n a newline.
Unlike echo, printf does not add a newline for you, so always write \n at the end of the line.
A command's output comes in two streams: standard output and standard error.
> file overwrites a file with standard output, >> file appends to the end, and 2> file routes only standard error to a separate file.
Send good results to the report and errors to their own file, and tracking down a cause later gets much easier.
vi fmt.sh # open in the editor, write the following, and save with :wq
# #!/bin/sh
# printf '%s\t%s\n' name age # tab-separated header
# printf '%s\t%s\n' alice 30 # data row, lined up
# echo "done" >> fmt.log # append to the log
chmod +x fmt.sh
./fmt.sh
> (overwrite) or >> (append), and errors are split off to another file with 2>.| Syntax | Meaning | Example |
|---|---|---|
echo "$v" | Print a variable or string as-is | echo "$name" |
printf "%s\t%s\n" a b | Print with a format (tab separator and explicit newline) | printf '%s\t%s\n' name age |
> f | Overwrite a file with standard output | echo line > report.txt |
>> f | Append standard output to a file | echo more >> report.txt |
2> err | Split only standard error into another file | cat missing 2> err.log |
Gathering a summary report into one file — here-doc and command substitution
For a report with a fixed layout, write the template as a here-doc and embed command results inside it.
The lines you write between cat > report.txt <<EOF and EOF go into the file as they are, and anywhere you write $(...), the command runs and its output is substituted in place.
An unquoted <<EOF expands variables and command substitutions; <<'EOF' (with single quotes) expands nothing and prints the text literally.
Pull aggregated values such as counts and sums in with command substitution around wc -l or grep -c.
Once the report is written, use an exit code to tell the caller whether the work succeeded.
exit 0 means success and exit 1 means something went wrong — a following &&, or a CI job, can then act on that.
vi summary.sh # open in the editor, write the following, and save with :wq
# #!/bin/sh
# log=access.log
# lines=$(wc -l < "$log") # count the lines
# cat > summary.txt <<REPORT # embed the value in the template
# --- access summary ---
# total lines: $lines
# REPORT
# echo "summary.txt created"
# exit 0
chmod +x summary.sh
$(wc -l) is substituted where you wrote $(...) in the here-doc template, so the whole report lands in one file.| Syntax | Meaning | Example |
|---|---|---|
<<EOF … EOF | here-doc that expands variables and command substitutions | cat <<EOF > t.txt |
<<'EOF' … EOF | here-doc that expands nothing and prints text literally | cat <<'EOF' > t.txt |
$(wc -l < f) | Pull an aggregated value in with command substitution | n=$(wc -l < access.log) |
exit 0 / exit 1 | Return a success or failure exit code | exit 0 |
Splitting standard output and errors into separate files
When a single command produces good results and errors at the same time, write > ok.txt 2> err.txt and standard output is saved to ok.txt while standard error goes to err.txt.
Because you can then check the results and the problems separately, this shape shows up a lot when designing logging for operations scripts.
ls /etc /no_such_dir > ok.txt 2> err.txt # listing to ok.txt, error to err.txt
cat ok.txt # the /etc listing (standard output)
cat err.txt # the /no_such_dir error (standard error)
> ok.txt and its standard error to 2> err.txt, saved separately at the same time.| Syntax | Meaning | Example |
|---|---|---|
cmd > ok 2> err | Send standard output and standard error to separate files at once | ls /etc > ok.txt 2> err.txt |
echo "…" 1>&2 | Send a message to the standard error side | echo failed 1>&2 |
Knowledge Check
Answer each question one by one.
Q2Which syntax routes only a command's standard error to a separate file?
Q3When you want the result of $(...) embedded inside a here-doc template, which opening tag do you use?