Learn by reading through in order

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
Routing where output goes
normal resultstandard output> overwrite>> appenderrorstandard error2> err.logto the reporterrors to their own file
Normal results go to the report with > (overwrite) or >> (append), and errors are split off to another file with 2>.
SyntaxMeaningExample
echo "$v"Print a variable or string as-isecho "$name"
printf "%s\t%s\n" a bPrint with a format (tab separator and explicit newline)printf '%s\t%s\n' name age
> fOverwrite a file with standard outputecho line > report.txt
>> fAppend standard output to a fileecho more >> report.txt
2> errSplit only standard error into another filecat missing 2> err.log

Build and run a script that prints formatted output and writes it to a file.

① Open format.sh with vi format.sh, press i to enter insert mode, write the formatted output and report-writing logic, then save with Esc:wq (you can copy the body from the answer panel and paste it in).

② Add execute permission with chmod +x format.sh.

③ Run it with ./format.sh and check the formatted output on screen.

④ Check the contents of the report you wrote out with cat table.txt. (Run it correctly and the explanation will appear.)

Linux console
0 / 4 completed
Loading Linux Terminal...

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
Embedding an aggregated result in a here-doc
access.logcount with $(wc -l)total = 5<<EOF … EOFembed $totalreport.txt writtenaggregateembed in the template
The count from $(wc -l) is substituted where you wrote $(...) in the here-doc template, so the whole report lands in one file.
SyntaxMeaningExample
<<EOF … EOFhere-doc that expands variables and command substitutionscat <<EOF > t.txt
<<'EOF' … EOFhere-doc that expands nothing and prints text literallycat <<'EOF' > t.txt
$(wc -l < f)Pull an aggregated value in with command substitutionn=$(wc -l < access.log)
exit 0 / exit 1Return a success or failure exit codeexit 0

Aggregate counts from a log, embed them in a here-doc template, and gather the report into a single file.

① Create the sample log with printf 'GET /a 200\nGET /b 404\nGET /c 200\nGET /d 500\nGET /e 200\n' > access.log.

② Open report.sh with vi report.sh and press i to enter insert mode. Write logic that aggregates the counts with command substitution and embeds them in a here-doc template, then save with Esc:wq (you can copy the body from the answer panel and paste it in).

③ Add execute permission with chmod +x report.sh.

④ Run it with ./report.sh, then check the aggregated values and the template in the generated report.txt with cat report.txt.

Linux console
0 / 3 completed
Loading Linux Terminal...

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)
Splitting one command's two streams
ls /etc /no_suchok.txt(results)err.txt(problems)> standard output2> standard error
A single command's standard output can go to > ok.txt and its standard error to 2> err.txt, saved separately at the same time.
SyntaxMeaningExample
cmd > ok 2> errSend standard output and standard error to separate files at oncels /etc > ok.txt 2> err.txt
echo "…" 1>&2Send a message to the standard error sideecho failed 1>&2

Build and run a script that routes one command's standard output and errors into separate files.

① Open split.sh with vi split.sh, press i to enter insert mode, write logic that routes standard output and errors to separate files, then save with Esc:wq (you can copy the body from the answer panel and paste it in).

② Add execute permission with chmod +x split.sh.

③ Run it with ./split.sh and check the line counts of ok.txt and err.txt shown on screen.

④ Check the standard output contents with cat ok.txt and the error contents with cat err.txt.

Linux console
0 / 5 completed
Loading Linux Terminal...
QUIZ

Knowledge Check

Answer each question one by one.

Q1In printf '%s\t%s\n' a b, what do \t and \n mean?

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?