Skip to content
ALB Wiki

Automation and Dev

This is an old revision of this page — revision 4 (1970-01-21 18:02:21 UTC). It may differ from the current revision.

The last layer is the personal one — the point where a working system becomes your system: jobs scheduled, sessions that survive disconnects, a config that versions itself, a development environment shaped to your hands. This chapter covers cron and systemd timers, tmux and screen, git as both tool and practice, and the dotfiles discipline that makes a system reproducible.

cron — the classic scheduler

crontab -e                     # edit YOUR crontab
crontab -l                     # list it
# min hour day month weekday  command
0  3   *   *   *    /usr/local/bin/backup.sh      # 3am daily
*/15 *   *   *   *    /usr/local/bin/check.sh     # every 15min
0  0   1   *   *    /usr/local/bin/monthly.sh     # the 1st
@daily /path/script.sh        # the readable form
@reboot /path/start.sh        # at boot

/etc/crontab + /etc/cron.d/ + /etc/cron.daily/hourly/weekly/monthly for system jobs. Cron's output mails to the user — MAILTO="" silences it; redirect to a log instead. The classic gotcha: cron's environment is minimal — scripts need full paths and exported vars.

systemd timers — the modern equivalent

# /etc/systemd/system/backup.timer
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
systemctl enable --now backup.timer
systemctl list-timers          # the scheduled world
journalctl -u backup.service   # its log

Timers beat cron where logging + dependencies matter; OnCalendar= reads like English; Persistent=true runs missed jobs after downtime — cron can't.

tmux — the complete map

tmux                        # new session
tmux new -s work            # named session
tmux ls                     # list
tmux attach -t work         # reattach — the superpower
tmux new -s x \; send-keys 'cmd' Enter \; detach   # scriptable
tmux kill-session -t work   # destroy
tmux kill-server            # all of them

# inside — Ctrl-b is the prefix:
Ctrl-b d      — detach
Ctrl-b c      — new window    Ctrl-b , — rename it    Ctrl-b w — window list
Ctrl-b %      — split vertical    Ctrl-b "  — split horizontal
Ctrl-b arrows — move panes       Ctrl-b { } — swap panes
Ctrl-b x      — kill pane        Ctrl-b z — zoom pane
Ctrl-b [      — scrollback mode — q to exit, /to-search, Space copies
Ctrl-b s      — session list     Ctrl-b : — command mode
Ctrl-b ?      — the key map
:set -g mouse on            — the mouse config
Ctrl-b $      — rename session

Sessions survive SSH disconnects — the killer feature. tmux -CC (iTerm2) integrates; tmate shares sessions.

The environment files — the complete startup chain

# /etc/profile → /etc/profile.d/*.sh → ~/.bash_profile → ~/.bash_login → ~/.profile  (login)
# ~/.bashrc (interactive non-login)  # $BASH_ENV (non-interactive)
# ~/.bash_logout (logout)
# ~/.inputrc  — readline: how EVERYTHING reads input — set editing-mode vi
# ~/.profile — POSIX shell's own
# ~/.zshrc — zsh's
# ~/.tmux.conf ~/.vimrc ~/.gitconfig ~/.ssh/config ~/.config/*

~/.inputrc shapes every readline app — set editing-mode vi gives vi keys in bash, psql, python, everywhere readline reads.

tmux — sessions that survive

tmux                        # new session
tmux new -s work            # named
tmux ls                     # sessions
tmux attach -t work         # reattach — the superpower
# inside:  Ctrl-b d detach · Ctrl-b c new window · Ctrl-b % split · Ctrl-b " horizontal split
# Ctrl-b [ scrollback · Ctrl-b w window list · Ctrl-b , rename

Detach-and-reattach is the killer feature — ssh in, start a build, Ctrl-b d, disconnect, the build runs on; reconnect tomorrow, tmux attach, everything's there. screen is the classic equivalent; tmux is the modern one.

git — versioning everything, including the system

git init; git add .; git commit -m "first"
git status; git diff; git log --oneline
git checkout -b experiment      # branches = safe experiments
git merge experiment
git stash; git stash pop        # the clipboard
git clone url; git pull; git push
.gitignore                      # what NOT to version

Version your own work — scripts, configs, dotfiles, even notes. git init in ~/scripts, a repo for the dotfiles — the config becomes diff-able, recoverable, portable.

Dotfiles — the reproducible setup

# the setup as files
~/.bashrc  ~/.bash_profile  ~/.vimrc  ~/.tmux.conf  ~/.gitconfig  ~/.ssh/config
# the discipline: version them
mkdir ~/dotfiles; mv ~/.bashrc ~/dotfiles/
ln -s ~/dotfiles/.bashrc ~/.bashrc    # symlinked — the stow pattern
gnu stow dotfiles                     # or the tool

The dotfiles repo is the answer to "I rebuilt my machine" — clone it, symlink it, your environment travels. stow automates the symlinking; bare repos + git --git-dir=~/.dotfiles --work-tree=~ is the no-tool method.

The cron grammar — the five-field contract

# ┌───── minute (0–59)
# │ ┌─── hour (0–23)
# │ │ ┌─── day of month (1–31)
# │ │ │ ┌─── month (1–12)
# │ │ │ │ ┌─── day of week (0–7, 0 and 7 = Sun)
# │ │ │ │ │
* * * * *  command

*       — every
*/15    — every 15
0       — at 0
1,15    — the 1st and 15th
1-5     — range
0 3 * * *      — 3am daily
0 */6 * * *    — every 6 hours
0 0 * * 0      — Sunday midnight
0 9 1 * *      — 9am on the 1st
@daily @weekly @monthly @yearly @reboot    — the readable forms

Cron's environment is minimal — scripts need PATH set, full paths, no tty. MAILTO="" kills the mail; redirect output to a log instead.

The systemd timer grammar

[Timer]
OnCalendar=daily              # readable calendar spec
OnCalendar=*-*-* 03:00:00    # 3am daily — the precise form
OnCalendar=Mon *-*-* 09:00:00
OnCalendar=hourly / weekly / daily / monthly / yearly
OnBootSec=15min               # 15m after boot
OnUnitActiveSec=1h            # 1h after the service last ran
Persistent=true               # catch up on missed runs — cron can't
AccuracySec=1min              # batch wakeup — power-saving
RandomizedDelaySec=5m         # jitter — the thundering-herd fix

systemctl list-timers --all shows the next/elapsed runs; journalctl -u foo.timer the history.

The development environment — the assembled whole

export EDITOR=vim; export PAGER=less    # the env that shapes everything
alias ll='ls -lah'; alias ..='cd ..'    # the shortcuts
export PATH="$HOME/bin:$PATH"           # your own tools first
~/.inputrc                              # readline — how EVERYTHING reads input
history; Ctrl-R                         # the working memory

The pieces compound: a tuned .bashrc (aliases, PATH, PS1), .inputrc (readline keys), .vimrc, .tmux.conf, .gitconfig — the environment that feels like yours is these files, versioned.

The automation philosophy

Automate what's repeated: alias, a function, a script, a cron job — the four scales. &&-chains for one-offs; functions for reusable commands; scripts for multi-step; cron/timers for scheduled. The discipline isn't the tool — it's noticing the repetition.

Where it goes wrong

SymptomCause
cron job silently does nothingMinimal env — full paths, or MAILTO ate the error
tmux session gone after rebootSessions don't persist through reboots — tmux-resurrect or scripts
ssh config ignored~/.ssh/config needs Host matching exactly
Dotfiles broke on a new machineA host-specific var — conditionals or per-host files
git committed a secret.gitignore + pre-commit checks
Systemd timer didn't run after downtimePersistent=true missing

Exercises

  1. Write a crontab entry; run it; find its logged output.
  2. A systemd timer for a daily job — compare to the cron form.
  3. tmux: start a build, detach, reattach — feel the superpower.
  4. git init your ~/scripts; commit your dotfiles.
  5. Write the .bashrc additions that would make a fresh system yours.

Timeline

ToolThe layer
cronScheduled jobs
systemd timersCron + logging
tmuxPersistent sessions
gitVersioned work
dotfilesThe reproducible self

See also

Categories: Handbook · Linux · Linux Handbook
This page was last edited 1970-01-21 18:02:21 UTC by Devin. What links here