The VikiD Truth

Knowledge base / Computing / Linux & the command line

BASH | Bash Cookbook |

Vikid’s Bash Cookbook

Here is the truth about the shell: most of what people call “Linux skills” is really a dozen shell habits, repeated until they are automatic. This cookbook is where I keep the recipes I actually reach for, with the reasons behind them, so they make sense rather than just work.

What it is, in plain words

Bash (the “Bourne Again SHell”, by Brian Fox for the GNU project in 1989) is both an interactive command line and a programming language. Bash 5.3 is the current version in 2026. When you type a line, Bash:

  1. splits it into words, honouring quotes;
  2. expands variables ($USER), command substitutions ($(date)), arithmetic ($((1+2))), braces ({a,b}) and globs (*.md);
  3. sets up redirections (>, <, |);
  4. finds the command (alias, function, builtin, or a program on $PATH) and runs it.

Nearly every shell surprise is one of those four steps doing something you did not expect. The recipes below are grouped so that each one exercises one of them.

Why it matters

An everyday analogy: a kitchen with good knives

You do not need a gadget for every job if you have three good knives and know how to use them. grep, sed, awk, find, xargs and pipes are the knives. Recipes are just the ways cooks combine them.

A hands-on example: recipes I use weekly

# Which shell am I in, and which bash?
echo "$0"; bash --version | head -1

# What is this command, really? (alias, function, builtin or file)
type -a ls

# Find big files under the current directory
find . -type f -size +100M -exec ls -lh {} + 2>/dev/null

# Search code, skipping .git, then count matches per file
grep -rIn --exclude-dir=.git 'TODO' . | cut -d: -f1 | sort | uniq -c | sort -rn

# Rename *.jpeg to *.jpg safely (parameter expansion, no external tools)
for f in *.jpeg; do [ -e "$f" ] && mv -n -- "$f" "${f%.jpeg}.jpg"; done

# Run something on every file, NUL-separated so spaces in names are safe
find . -name '*.md' -print0 | xargs -0 wc -w | tail -1

# Repeat the last command with sudo
sudo !!

# Quick backup with a date stamp
cp -a notes.org "notes.org.$(date +%F)"

The quoting examples further down are the most important on the page. The rule: double-quote every variable expansion unless you have a reason not to. "$f" survives a file called my notes.txt; $f becomes two words.

A safe script header I start everything with:

#!/usr/bin/env bash
set -euo pipefail          # stop on errors, unset vars, and failed pipes
IFS=$'\n\t'                # split only on newlines and tabs

Run shellcheck script.sh (xbps-install -S shellcheck on Vikix) before trusting a script. It catches most quoting mistakes for you.

Common misconceptions

Connections

The recipes

Some Simple Stuff

bash --version

ls -adFlLQrRS1

pwd -L, pwd -P

type which, type -a which

apropos zip => man -k, locate which

find

stat, file -b

chsh -s /bin/bash

passwd -el

sudo cat /etc/shells

Common Shell Variables

$USER
$-             list all current option flags

Download a website

wget -r -np -k http://somesite.com

Options:

Quoting

echo value is $3?!
echo "value is $3?!"
echo 'value is $3?!'

!" is history substitution

Builtin Commands

ls () {
    builtin ls "@"
    echo "using defined ls"
}

Interactive

#!/usr/bin/env bash

case "$-" in
   *i*)
      echo "interative"
   *)
      echo "not interactive"
esac

Last edited · 12 revisions

Tags: #Computing