Logging and User-Friendly Output
Prerequisites: Functions, printf and here documents
Good scripts tell you what they're doing, separate errors from normal output, and can be made quieter or more detailed.
A small logging library
LOG_LEVEL=${LOG_LEVEL:-info}
_level_num() {
case "$1" in debug) echo 0 ;; info) echo 1 ;; warn) echo 2 ;; error) echo 3 ;; esac
}
log() {
local level=$1; shift
(( $(_level_num "$level") >= $(_level_num "$LOG_LEVEL") )) || return 0
printf '[%s] %-5s %s\n' "$(TZ=UTC date -d @0 +%T)" "${level^^}" "$*" >&2
}
log debug "Connecting to cache"
log info "Starting import"
log warn "3 rows skipped"
log error "Import failed"
[00:00:00] INFO Starting import
[00:00:00] WARN 3 rows skipped
[00:00:00] ERROR Import failed
- Messages go to stderr (
>&2), so they don't mix with the script's real output, which might be piped into another program. - A
LOG_LEVELenvironment variable controls verbosity;debugmessages are hidden by default. Run withLOG_LEVEL=debug ./script.shto see them. - In real scripts, use
date '+%F %T'for the current time — the example uses a fixed timestamp so its output is repeatable.
Colours — only on a terminal
# illustrative
if [[ -t 2 ]]; then
red=$'\e[31m'; green=$'\e[32m'; reset=$'\e[0m'
else
red=''; green=''; reset=''
fi
echo "${green}✓ tests passed${reset}" >&2
echo "${red}✗ deploy failed${reset}" >&2
[[ -t 2 ]] checks whether stderr is a terminal. When output is redirected
to a file or a CI log, colour codes would just be clutter. Many tools also
honour the NO_COLOR environment variable.
Progress for long tasks
total=5
for i in $(seq 1 "$total"); do
printf 'Processing %d/%d\n' "$i" "$total"
done
Processing 1/5
Processing 2/5
Processing 3/5
Processing 4/5
Processing 5/5
On an interactive terminal, printing \r instead of \n rewrites the same
line, giving a live counter.
Logging to a file as well
exec > >(tee -a script.log) 2>&1 near the top of a script sends all
output to both the terminal and a log file. For system services,
logger "message" writes to the system log (journalctl on systemd
machines).