,THE LAST LAYER IS THE PERSONAL ONE THE POINT WHERE A WORKING SYSTEM BECOMES YOUR SYSTEM3 JOBS SCHEDULED1 SESSIONS THAT SURVIVE DISCONNECTS1 A CONFIG THAT VERSIONS ITSELF1 A DEVELOPMENT ENVIRONMENT SHAPED TO YOUR HANDS4 ,THIS CHAPTER COVERS CRON AND SYSTEMD TIMERS1 TMUX AND SCREEN1 GIT AS BOTH TOOL AND PRACTICE1 AND THE DOTFILES DISCIPLINE THAT MAKES A SYSTEM REPRODUCIBLE4 CRON THE CLASSIC SCHEDULER CRONTAB -;E _? EDIT ,,YOUR CRONTAB CRONTAB -;L _? LIST IT _? MIN HOUR DAY MONTH WEEKDAY COMMAND #J #C "9 "9 "9 _/USR_/LOCAL_/BIN_/BACKUP4SH _? #C;AM DAILY "9_/#AE "9 "9 "9 "9 _/USR_/LOCAL_/BIN_/CHECK4SH _? EVERY #AEMIN #J #J #A "9 "9 _/USR_/LOCAL_/BIN_/MONTHLY4SH _? THE #AST @ADAILY _/PATH_/SCRIPT4SH _? THE READABLE FORM @AREBOOT _/PATH_/START4SH _? AT BOOT _/ETC_/CRONTAB "6 _/ETC_/CRON4D_/ "6 _/ETC_/CRON4DAILY_/HOURLY_/WEEKLY_/MONTHLY FOR SYSTEM JOBS4 ,CRON'S OUTPUT MAILS TO THE USER ,,MAILTO"700 SILENCES IT2 REDIRECT TO A LOG INSTEAD4 ,THE CLASSIC GOTCHA3 CRON'S ENVIRONMENT IS MINIMAL SCRIPTS NEED FULL PATHS AND EXPORTED VARS4 SYSTEMD TIMERS THE MODERN EQUIVALENT _? _/ETC_/SYSTEMD_/SYSTEM_/BACKUP4TIMER .<,TIMER.> ,ON,CALENDAR"7DAILY ,PERSISTENT"7TRUE .<,INSTALL.> ,WANTED,BY"7TIMERS4TARGET SYSTEMCTL ENABLE --NOW BACKUP4TIMER SYSTEMCTL LIST-TIMERS _? THE SCHEDULED WORLD JOURNALCTL -;U BACKUP4SERVICE _? ITS LOG ,TIMERS BEAT CRON WHERE LOGGING "6 DEPENDENCIES MATTER2 ,ON,CALENDAR"7 READS LIKE ,ENGLISH2 ,PERSISTENT"7TRUE RUNS MISSED JOBS AFTER DOWNTIME CRON CAN'T4 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 _*2 SEND-KEYS 'CMD' ,ENTER _*2 DETACH _? SCRIPTABLE TMUX KILL-SESSION -;T WORK _? DESTROY TMUX KILL-SERVER _? ALL OF THEM _? INSIDE ,CTRL-;B IS THE PREFIX3 ,CTRL-;B ;D DETACH ,CTRL-;B ;C NEW WINDOW ,CTRL-;B 1 RENAME IT ,CTRL-;B ;W WINDOW LIST ,CTRL-;B .0 SPLIT VERTICAL ,CTRL-;B ,7 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 EXIT1 _/TO-SEARCH1 ,SPACE COPIES ,CTRL-;B ;S SESSION LIST ,CTRL-;B 3 COMMAND MODE ,CTRL-;B 8 THE KEY MAP 3SET -;G MOUSE ON THE MOUSE CONFIG ,CTRL-;B @S RENAME SESSION ,SESSIONS SURVIVE ,,SSH DISCONNECTS THE KILLER FEATURE3 SSH IN1 START A BUILD1 ,CTRL-;B ;D1 DISCONNECT1 THE BUILD RUNS ON2 RECONNECT TOMORROW1 TMUX ATTACH1 EVERYTHING'S THERE4 SCREEN IS THE CLASSIC EQUIVALENT2 TMUX IS THE MODERN ONE4 TMUX -,,CC " INTEGRATES2 TMATE SHARES SESSIONS4 ,THE ENVIRONMENT FILES THE COMPLETE STARTUP CHAIN _? _/ETC_/PROFILE _/ETC_/PROFILE4D_/"94SH ,,FIRST OF @9_/4BASH.-PROFILE ,,OR @9_/4BASH.-LOGIN ,,OR @9_/4PROFILE " _? @9_/4BASHRC " _? @S,,BASH.-,,ENV " _? @9_/4BASH.-LOGOUT " _? @9_/4INPUTRC READLINE3 HOW ,,EVERYTHING READS INPUT SET EDITING-MODE VI _? @9_/4PROFILE ,,POSIX SHELL'S OWN _? @9_/4ZSHRC ZSH'S _? @9_/4TMUX4CONF @9_/4VIMRC @9_/4GITCONFIG @9_/4SSH_/CONFIG @9_/4CONFIG_/"9 @9_/4INPUTRC SHAPES EVERY READLINE APP SET EDITING-MODE VI GIVES VI KEYS IN BASH1 PSQL1 PYTHON1 EVERYWHERE READLINE READS4 GIT VERSIONING EVERYTHING1 INCLUDING THE SYSTEM GIT INIT2 GIT ADD 42 GIT COMMIT -;M 8FIRST0 GIT STATUS2 GIT DIFF2 GIT LOG --ONELINE GIT CHECKOUT -;B EXPERIMENT _? BRANCHES "7 SAFE EXPERIMENTS GIT MERGE EXPERIMENT GIT STASH2 GIT STASH POP _? THE CLIPBOARD GIT CLONE URL2 GIT PULL2 GIT PUSH 4GITIGNORE _? WHAT ,,NOT TO VERSION ,VERSION YOUR OWN WORK SCRIPTS1 CONFIGS1 DOTFILES1 EVEN NOTES4 GIT INIT IN @9_/SCRIPTS1 A REPO FOR THE DOTFILES THE CONFIG BECOMES DIFF-ABLE1 RECOVERABLE1 PORTABLE4 ,DOTFILES THE REPRODUCIBLE SETUP _? THE SETUP AS FILES @9_/4BASHRC @9_/4BASH.-PROFILE @9_/4VIMRC @9_/4TMUX4CONF @9_/4GITCONFIG @9_/4SSH_/CONFIG _? THE DISCIPLINE3 VERSION THEM MKDIR @9_/DOTFILES2 MV @9_/4BASHRC @9_/DOTFILES_/ LN -;S @9_/DOTFILES_/4BASHRC @9_/4BASHRC _? SYMLINKED THE STOW PATTERN GNU STOW DOTFILES _? OR THE TOOL ,THE DOTFILES REPO IS THE ANSWER TO 8,I REBUILT MY MACHINE0 CLONE IT1 SYMLINK IT1 YOUR ENVIRONMENT TRAVELS4 STOW AUTOMATES THE SYMLINKING2 BARE REPOS "6 GIT --GIT-DIR"7@9_/4DOTFILES --WORK-TREE"7@9 IS THE NO-TOOL METHOD4 ,THE CRON GRAMMAR THE FIVE-FIELD CONTRACT _? MINUTE "<#J#EI"> _? HOUR "<#J#BC"> _? DAY OF MONTH "<#A#CA"> _? MONTH "<#A#AB"> _? DAY OF WEEK "<#J#G1 #J AND #G "7 ,SUN"> _? "9 "9 "9 "9 "9 COMMAND "9 EVERY "9_/#AE EVERY #AE #J AT #J #A1AE THE #AST AND #AETH #A-#E RANGE #J"C "9 "9 "9 #C;AM DAILY #J "9_/#F "9 "9 "9 EVERY #F HOURS #J"J "9 "9 #J ,SUNDAY MIDNIGHT #J"I"#A "9 "9 #I;AM ON THE #AST @ADAILY @AWEEKLY @AMONTHLY @AYEARLY @AREBOOT THE READABLE FORMS ,CRON'S ENVIRONMENT IS MINIMAL SCRIPTS NEED ,,PATH SET1 FULL PATHS1 NO TTY4 ,,MAILTO"700 KILLS THE MAIL2 REDIRECT OUTPUT TO A LOG INSTEAD4 ,THE SYSTEMD TIMER GRAMMAR .<,TIMER.> ,ON,CALENDAR"7DAILY _? READABLE CALENDAR SPEC ,ON,CALENDAR"7"9-"9-"9 #JC3#JJ3#JJ _? #C;AM DAILY THE PRECISE FORM ,ON,CALENDAR"7,MON "9-"9-"9 #JI3#JJ3#JJ ,ON,CALENDAR"7HOURLY _/ WEEKLY _/ DAILY _/ MONTHLY _/ YEARLY ,ON,BOOT,SEC"7#AEMIN _? #AE;M AFTER BOOT ,ON,UNIT,ACTIVE,SEC"7#A;;H _? #A;;H AFTER THE SERVICE LAST RAN ,PERSISTENT"7TRUE _? CATCH UP ON MISSED RUNS CRON CAN'T ,ACCURACY,SEC"7#AMIN _? BATCH WAKEUP POWER-SAVING ,RANDOMIZED,DELAY,SEC"7#E;M _? JITTER THE THUNDERING-HERD FIX SYSTEMCTL LIST-TIMERS --ALL SHOWS THE NEXT_/ELAPSED RUNS2 JOURNALCTL -;U FOO4TIMER THE HISTORY4 ,THE DEVELOPMENT ENVIRONMENT THE ASSEMBLED WHOLE EXPORT ,,EDITOR"7VIM2 EXPORT ,,PAGER"7LESS _? THE ENV THAT SHAPES EVERYTHING ALIAS LL"7'LS -LAH'2 ALIAS 44"7'CD 44' _? THE SHORTCUTS EXPORT ,,PATH"70@S,,HOME_/BIN3@S,,PATH0 _? YOUR OWN TOOLS FIRST @9_/4INPUTRC _? READLINE HOW ,,EVERYTHING READS INPUT HISTORY2 ,CTRL-;,R _? THE WORKING MEMORY ,THE PIECES COMPOUND3 A TUNED 4BASHRC "1 4INPUTRC "1 4VIMRC1 4TMUX4CONF1 4GITCONFIG THE ENVIRONMENT THAT FEELS LIKE YOURS IS THESE FILES1 VERSIONED4 ,THE AUTOMATION PHILOSOPHY ,AUTOMATE WHAT'S REPEATED3 ALIAS1 A FUNCTION1 A SCRIPT1 A CRON JOB THE FOUR SCALES4 @&@&-CHAINS FOR ONE-OFFS2 FUNCTIONS FOR REUSABLE COMMANDS2 SCRIPTS FOR MULTI-STEP2 CRON_/TIMERS FOR SCHEDULED4 ,THE DISCIPLINE ISN'T THE TOOL IT'S NOTICING THE REPETITION4 ,WHERE IT GOES WRONG ,SYMPTOM ,CAUSE CRON JOB SILENTLY DOES NOTHING ,MINIMAL ENV FULL PATHS1 OR ,,MAILTO ATE THE ERROR TMUX SESSION GONE AFTER REBOOT ,SESSIONS DON'T PERSIST THROUGH REBOOTS TMUX-RESURRECT OR SCRIPTS SSH CONFIG IGNORED @9_/4SSH_/CONFIG NEEDS ,HOST MATCHING EXACTLY ,DOTFILES BROKE ON A NEW MACHINE ,A HOST-SPECIFIC VAR CONDITIONALS OR PER-HOST FILES GIT COMMITTED A SECRET 4GITIGNORE "6 PRE-COMMIT CHECKS ,SYSTEMD TIMER DIDN'T RUN AFTER DOWNTIME ,PERSISTENT"7TRUE MISSING ,EXERCISES #A4 ,WRITE A CRONTAB ENTRY2 RUN IT2 FIND ITS LOGGED OUTPUT4 #B4 ,A SYSTEMD TIMER FOR A DAILY JOB COMPARE TO THE CRON FORM4 #C4 TMUX3 START A BUILD1 DETACH1 REATTACH FEEL THE SUPERPOWER4 #D4 GIT INIT YOUR @9_/SCRIPTS2 COMMIT YOUR DOTFILES4 #E4 ,WRITE THE 4BASHRC ADDITIONS THAT WOULD MAKE A FRESH SYSTEM YOURS4 ,TIMELINE ,TOOL ,THE LAYER CRON ,SCHEDULED JOBS SYSTEMD TIMERS ,CRON "6 LOGGING TMUX ,PERSISTENT SESSIONS GIT ,VERSIONED WORK DOTFILES ,THE REPRODUCIBLE SELF ,SEE ALSO - ,SHELL ,SCRIPTING ,INSIDE A ,LINUX ,SYSTEM ,EDITORS ,LINUX