Ein roter Prompt auf Produktion
Die meisten Verwechslungen des Servers passieren, weil zwei Terminals gleich aussehen. Der Prompt ist das, was Sie kurz vor dem Drücken von Return lesen, ändern Sie ihn also dort. Fügen Sie dies am Ende von ~/.bashrc auf dem Server hinzu. Es muss ans Ende, weil die .bashrc der Distribution PS1 früher setzt und sonst überschreiben würde:
PS1='\[\e[1;37;41m\] PRODUCTION \[\e[0m\] \u@\h:\w\$ '
Das zeigt PRODUCTION in Weiß auf Rot, danach den normalen Benutzer, Host und Ordner. \[ und \] sagen bash, dass die Farbcodes keine Breite haben, lange Befehle werden also weiterhin richtig umbrochen.
Tragen Sie dieselbe Zeile in /root/.bashrc ein: In unserem Test zeigte sudo -i das rote Etikett nur, weil auch diese Datei es enthielt. Für Staging nehmen Sie Gelb mit \e[1;30;43m. Es wirkt nur für interaktive bash, andere Shells brauchen ihre eigene Einstellung.


tmux-Leiste und Terminal einfärben
Wenn Sie auf dem Server tmux nutzen, färben Sie dessen Statusleiste, dort in ~/.tmux.conf:
set -g status-style bg=red,fg=white,bold
set -g status-left " PRODUCTION "
Ob es geladen wurde, prüfen Sie mit tmux show -g status-style.
Auf Ihrem eigenen Rechner können die meisten Terminal-Apps einen Host in einem eigenen Profil öffnen. Geben Sie Produktion ein Fenster mit dunkelrotem Hintergrund. Sie können die Farbe auch von Ihrer SSH-Konfiguration setzen lassen, in Terminals, die die Sequenz OSC 11 unterstützen:
Host prod-*
PermitLocalCommand yes
LocalCommand printf '\033]11;#400000\007'
Die Farbe geht beim Abmelden nicht von selbst zurück, und die Unterstützung ist unterschiedlich, probieren Sie es also zuerst in Ihrem Terminal aus.
Bei vielen Servern helfen klare Namen und Gruppen so viel wie Farben: siehe viele SSH-Server verwalten.
Dateien sicher löschen
GNU rm verweigert den schlimmsten Fall bereits:
$ rm -rf /
rm: it is dangerous to operate recursively on '/'
rm: use --no-preserve-root to override this failsafe
Das schützt nur das buchstäbliche /. Bei rm -rf /* erweitert die Shell zuerst den Stern, rm erhält also /bin, /etc und den Rest, und die Prüfung greift nicht. Ein verirrtes Leerzeichen in rm -rf /var/app /* bewirkt das aus Versehen. Diese Gewohnheiten helfen mehr:
- Erst ansehen, dann löschen. Setzen Sie
echodavor, um zu sehen, wozu ein Glob erweitert wird:echo rm -rf /tmp/app/*. Entfernen Sie dann dasecho. - Mit
&&verbinden, nicht mit;. Beicd /var/app/tmp && rm -rf ./*stoppt ein fehlgeschlagenescddort. Mit;läuft das Löschen in dem Ordner, in dem Sie gerade sind. - Variablen in Skripten absichern.
rm -rf "${DIR:?}/"bricht mit einem Fehler ab, wennDIRleer ist, wo ein einfaches"$DIR/"zu/würde. Auchset -uam Anfang eines Skripts stoppt bei nicht gesetzten Variablen. - Erst verschieben, später löschen.
mvin einen Ablageordner lässt sich rückgängig machen.rmnicht. - Nutzen Sie
rm -I. Es fragt einmal nach, bevor mehr als drei Dateien oder rekursiv gelöscht werden. Wer nichts antwortet, löscht nichts, wie in unserem Test. - Nutzen Sie
--preserve-root=all. Es lehnt auch einen Ordner auf einem anderen Dateisystem als sein Elternordner ab, würde also eine eingehängte Platte ablehnen:rm: skipping '/dev/shm', since it's on a different device.
Die letzten beiden können in einen Alias auf dem Server, alias rm='rm -I --preserve-root=all'. Aliase gelten nur für interaktive Shells, nicht für Skripte oder für sudo rm, und diese Optionen gibt es nur bei GNU.
Zuerst ein Dry Run
| Befehl | Vorschau |
|---|---|
| rsync | rsync -an --delete --itemize-changes src/ dst/ |
| find | zuerst find . -name '*.tmp' -print, dann -print durch -delete ersetzen |
| git clean | git clean -n |
| apt-get | apt-get -s remove package |
Bei SQL führen Sie zuerst BEGIN; aus, dann die Anweisung, prüfen die Zeilenzahl und schließen mit COMMIT; oder ROLLBACK; ab. Das gilt nicht für Anweisungen, die Ihre Datenbank selbst committet. MySQL tut das zum Beispiel bei Tabellenänderungen.
Mehrere Zeilen einfügen
In einem Terminal wirkt ein Zeilenumbruch in eingefügtem Text wie Return, ein Einfügen kann also Befehle ausführen, bevor Sie sie gelesen haben. Bracketed Paste löst das. Das Terminal markiert den eingefügten Text, und die Shell fügt ihn ein, ohne etwas auszuführen. Wir haben zwei echo-Zeilen über tmux in bash eingefügt:
- Mit eingeschalteter Funktion standen beide Zeilen am Prompt, und nichts lief bis zum Return.
- Mit ausgeschalteter Funktion lief die erste Zeile sofort nach dem Einfügen.
In aktuellen bash-Versionen ist sie standardmäßig an. Prüfen Sie es mit diesem Befehl in einer interaktiven Shell:
bind -v | grep bracketed-paste
Steht dort off, fügen Sie set enable-bracketed-paste on zu ~/.inputrc hinzu. Es hilft nur dort, wo das Programm darum bittet. Beim Einfügen in ein Programm, das es nicht tut, oder in eine alte Shell, läuft es weiter Zeile für Zeile.
Was das alles nicht kann
Eine Prompt-Farbe hilft nur, wenn Sie hinsehen. Sie schützt kein Skript, keinen Cronjob und keinen Befehl, der mit ssh server 'command' läuft und nie einen Prompt zeigt. Aliase lassen sich umgehen, und nichts davon stoppt einen Fehler in den Argumenten eines Befehls, den Sie ausführen wollten.
Behalten Sie also die größeren Sicherungen: getestete Backups, getrennte Konten und Schlüssel für Produktion und möglichst wenig sudo für jede Person. Für enge Regeln siehe sudo über SSH.
Fragen
Wie mache ich den Bash-Prompt auf einem Produktionsserver rot?
Setzen Sie PS1 mit einem Farbcode für roten Hintergrund ans Ende von ~/.bashrc auf diesem Server, und in /root/.bashrc für sudo -i. Ans Ende, damit das PS1 der Distribution es nicht überschreibt.
Funktioniert rm -rf / unter Linux noch?
GNU rm verweigert das wörtliche /, außer mit --no-preserve-root. rm -rf /* schützt es nicht, weil die Shell den Stern vorher in alle Ordner der obersten Ebene erweitert.
Wie sehe ich vorher, was ein Befehl löschen würde?
Setzen Sie echo davor, um zu sehen, wozu ein Muster wird, oder nutzen Sie den Probelauf: rsync -n, git clean -n oder find mit -print vor -delete.
Quellen
- GNU-coreutils-Handbuch: rm und die Sonderbehandlung von /
- Bash-Handbuch: Syntax der Readline-Init-Datei
- tmux(1), OpenBSD-Handbuch
- ssh_config(5), OpenBSD-Handbuch