Skip to content
ALB Wiki

Diff — Automation and Dev

Comparing rev 5 → rev 6

{{infobox
| title = Automation & the Dev Environment
| chapter = Linux Handbook, chapter 29 — cron, systemd timers, tmux, git, dotfiles, the lived-in system
| core | A system becomes yours: scheduled jobs, persistent sessions, versioned config
| tools | cron · systemd timers · tmux/screen · git · stow/dotfiles · ssh config
| skills | scheduling · multiplexing · versioning your own setup
| next | The capstone — the philosophy and the map
}}
**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
```sh
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
```ini
# /etc/systemd/system/backup.timer
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
```
```sh
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
```sh
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: 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. `tmux -CC` (iTerm2) integrates; `tmate` shares sessions.
## The environment files — the complete startup chain
```sh
# /etc/profile → /etc/profile.d/*.sh → FIRST of ~/.bash_profile OR ~/.bash_login OR ~/.profile  (login — bash stops at the first found)
# ~/.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.
## git — versioning everything, including the system
```sh
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
```sh
# 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
```text
# ┌───── 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
```ini
[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
```sh
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
| Symptom | Cause |
| --- | --- |
| cron job silently does nothing | Minimal env — full paths, or `MAILTO` ate the error |
| tmux session gone after reboot | Sessions don't persist through reboots — tmux-resurrect or scripts |
| ssh config ignored | `~/.ssh/config` needs `Host` matching exactly |
| Dotfiles broke on a new machine | A host-specific var — conditionals or per-host files |
| `git` committed a secret | `.gitignore` + pre-commit checks |
| Systemd timer didn't run after downtime | `Persistent=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
| Tool | The layer |
| --- | --- |
| cron | Scheduled jobs |
| systemd timers | Cron + logging |
| tmux | Persistent sessions |
| git | Versioned work |
| dotfiles | The reproducible self |
## See also
- [[Shell Scripting]] · [[Inside a Linux System]] · [[Editors]] · [[Linux]]
[[Category:Linux]]
[[Category:Handbook]]
+
[[Category:Linux Handbook]]