Magic Line

9. Dezember 2012 at 11:15

Shebang

Auf Linux und anderen unixartigen Systemen steht in der ersten Zeile eines Scripts ein Shebang (#!) gefolgt vom Pfad des Interpreters für dieses Script.

Bash-Scripte starten oft mit #!/bin/bash wärend Perl-Scripte mit #!/usr/bin/perl starten. Dem Betriebsystem hilft diese Zeile, direkt den richtigen Interpreter für dieses Script zu finden und so richtig mit der Datei umzugehen.

In vielen Anleitungen wird #!/bin/sh für Shellscripte empfohlen. Ich bin kein Fan davon, denn /bin/sh ist ein Symlink auf die bevorzugte Shell dieses Systems. Debian benutzt hier die dash, manche Admins bevorzugen aber auch die Korn Shell oder die Z-Shell. Hinter /bin/sh kann also je nach System eine andere Shell stehen.

Ich benutze /bin/bash und stelle damit sicher, dass mein unter der Bash geprüfte Script auch auf einer Bash ausgeführt wird. Aber ein BSD User hat mich neulich bekehrt, künftig „/usr/bin/env bash“ zu benutzen.

Der Grund dafür ist folgender: Nicht alle unixartigen Systeme legen die Bash in /bin ab. Manche Systeme haben diese unter /usr/bin. Gibt man nun /bin/bash im Script an, wird das starten des Scripts scheitern.

env ist ein Kommando, dass auf unixartigen Systemen immer in /usr/bin liegt und das Kommando im Parameter (hier: bash) innerhalb des Suchpfades des Systems (PATH-Variable) sucht und startet.

Mit env spielt es also keine Rolle mehr, ob die Shell in /bin, in /usr/bin oder sonstwo im Suchpfad liegt.

Nun, künftig starten meine Scripte also so:
#!/usr/bin/env bash

Das farbige Bash Prompt

19. November 2012 at 20:15

Beispiel meines PromptsEin ehemaliger Arbeitskollege hat mich auf die Idee gebracht, mein geliebtes Prompt mal zu veröffentlichen.

Vor langer Zeit störte mich auf der Shell oft, dass man beim Arbeiten mit langen Ausgaben oft den Anfang der Ausgabe suchen mußte. Das war teilweise gar nicht so nicht einfach, wenn man mehrere ähnlich aussehende Config-Files nacheinander anzeigt, muss man schon genau schauen, wo dazwischen das Prompt steht.

Die Lösung war einfach: Ein farbiges Prompt. So erkennt man sehr schnell die Trennung und wenn das Prompt dann noch eine Leerzeile einbaut, wird es richtig schnell übersichtlich.

Folgende Informationen wollte ich noch im Prompt sehen:

  • Benutzername
  • Hostname
  • Aktuelles Arbeitsverzeichnis
  • Exitcode des letzten Kommandos

Der Exitcode (in Spitzen Klammern, hier im Beispiel ‚0‘) ist für’s Scripten sehr hilfreich, da man direkt beim Ausprobieren eines Kommandos an der Shell sieht, welcher Exitcode vom Programm zurückgegeben wird. So weiß ich gleich, ob es klappt und welchen Exitcode mein Script beim Ausführen des Kommandos erwarten darf.

Zusätzlich zum Prompt setze ich auf meinem System auch gleich noch einen Alias für ‚ls‘, damit dort immer die lange Ausgabe ausgegeben wird und die Einträge auch gleich in passenden Farben erscheinen.

In Summe sieht das dann bei mir so aus:

export PS1='\n\[\033[1;32m\]\u@\h: \w\n<$?> $ \[\033[0m\]'
alias ls='ls -AlFh --color=auto'
export LS_OPTIONS='--color=auto'
export LS_COLORS='no=00;37:fi=00;37:di=01;37:ln=01;33:pi=00;36:so=00;36:do=00;36:bd=00;36:cd=00;36:or=00;33:ex=01;36:';

Um das Prompt (Umgebungsvariable PS1) kurz zu erklären:

  • \n ist ein Enter
  • \[\033[{code}m\] = Ansi Escape Farbcode (siehe dazu Linupedia und Wikipedia)
  • \u ist der aktuell angemeldete Benutzer
  • \h ist der Hostname
  • \w ist das aktuelle Verzeichnis (working directory)
  • $? ist der Exitcode des letzten Programms
  • $ ist das Prompt-Zeichen (abhängig davon, ob man Benuter oder Root ist)

Die ‚1;32m‘ in der ersten Zeile ist der Farbcode:

  • 0;30m – Schwarz
  • 1;30m – Dunkelgrau
  • 0;31m – Rot
  • 1;31m – Hellrot
  • 0;32m – Grün
  • 1;32m – Hellgrün
  • 0;33m – Braun
  • 1;33m – Gelb
  • 0;34m – Blau
  • 1;34m – Hellblau
  • 0;35m – Violett
  • 1;35m – Hellviolett
  • 0;36m – Türkis
  • 1;36m – Helltürkis
  • 0;37m – Hellgrau
  • 1;37m – Weiß

Das ganze läßt sich dann z.B. in der ~/.bashrc eintragen, so dass es bei jedem Login gleich verfügbar ist.

Ich mache dies meist aber nicht so. Es gab in meinem Job schon Diskussionen mit anderen Admins, die mein Prompt nicht sinnvoll fanden oder ihr eigenes lieber hatten. So haben wir uns darauf geeinigt, keine Farben in der .bashrc zu speichern und stattdessen im Home-Verzeichnis eine Datei mit dem eigenen Prompt anzulegen.

Bei mir heißt die Datei ~/prompt_mbutschek und enthält obige Zeilen. Nach dem Login gebe ich ein ‚. pr[tab]‘, was dann zu ‚. prompt_mbutschek‘ wird. Damit importiere ich die Einstellungen in die aktuelle Bash-Sitzung. Andere Admins haben dagegen das Standardprompt und werden durch meine Liebe zum bunten Prompt nicht gestört.

Bash History mit Zeitstempel

17. September 2008 at 19:00

Seit Version 3 hat die Linux-Shell ‚Bash‘ ein nettes Feature: Sie kann in der History nicht nur die eingegebenen Befehle speichern, sondern auch Datum und Uhrzeit dazu.

Für mich als Systems Engineer in einem RZ eine nette Sache. Bei einem Problem kann ich zwar per ‚history‘ sehen, welches Kommando dazu führte und per ‚last‘ finde ich schnell heraus, wer meiner Kollegen wann auf dem Server war, doch helfen beide Informationen meist nichts, wenn ich nicht feststellen kann, WANN das Kommando eingegeben wurde.

Das funktioniert ganz einfach: Die Umgebungsvariable HISTTIMEFORMAT muss gesetzt sein und zwar mit dem Datumsformat gemäß strftime(3). Die Manpage verrät, dass %F das Datum und %T die Uhrzeit ist. Man muss die Variable nun nur noch im File ~/.bashrc setzen, schon wird bei jedem Befehl die Zeit gespeichert:

export HISTTIMEFORMAT='%F %T '

Wichtig ist das Leerzeichen zwischen dem %T und dem schließenden Quote. Ohne dieses gibt der Befehl ‚history‘ die Kommandos ohne Trennzeichen direkt hinter dem Datum aus.

Bedenken sollte man, dass dies weder das Manipulieren noch das Löschen der History verhindert. Man kann also damit keinen „Schutz“ bieten, sondern es nur unter Kollegen etwas einfacher machen, den richtigen Ansprechpartner schnell zu finden.