Die Art und Weise, wie ich jede Sprache gelernt habe, ist, mich nicht hinzusetzen und ein Buch darüber zu lesen, nur um sie zu lernen, sondern ein Ziel vor Augen zu haben:
Ich möchte X automatisieren.
Ich fange dann an, das Problem zu durchdenken, und benutze dann das Internet, um die Syntax herauszufinden, die mich von A nach B bringt.
Vor Jahren wollte ich zum Beispiel die Betriebszeiten meines Systems verfolgen, als ich gerade von Windows umgestiegen war, das alle 48 Stunden neu gebootet werden musste, und auch, weil ich ein großer Nerd war. Ich verspottete einen Online-Freund damit und wollte die Betriebszeit meines Systems hier zu Hause auf einer Webseite aktualisieren, die draußen im Internet auf einem Server in einem anderen Staat gehostet wurde.
Wie mache ich das?
Nun, zunächst einmal, wie mache ich ein Skript, das tatsächlich läuft?
#!/bin/bash <- Oh, specifies the script interpreter. LEARNED.
Hm, läuft immer noch nicht…
# chmod +x <- Oh, needs execute bit set. LEARNED.
Nun, wie bekomme ich die Betriebszeit? Nun, ich könnte den uptime-Befehl auseinandernehmen, aber eine der Funktionen, die ich wollte, war, meine „Rekord-Uptime“ zu verfolgen. Der uptime-Befehl von Linux zeigt die Betriebszeiten in einer für den Menschen lesbaren Form an:
13:23:54 up 32 days, 4:19
Nun, das ist ein bisschen grob, um es als größer oder kleiner als zu interpretieren. Es ist machbar, aber es muss einen einfacheren Weg geben. Ich frage mich, woher das Programm „uptime“ diese Daten bezieht? Ein wenig Googeln bringt mich auf das /proc-System:
/proc/uptime
Wie lese ich das? Es gibt mehrere Möglichkeiten. Der Weg, den ich aus Gewohnheit benutzte (und der wahrscheinlich der falsche Weg ist, da der cat-Befehl nicht wirklich dafür gedacht ist, ist:)
cat /proc/uptime
Was zurückgibt:
2780345.41 5546896.19
OK, jetzt haben wir nette Dezimalzahlen, die es einfacher machen, herauszufinden, ob es eine Rekordbetriebszeit ist. Aber wie kann ich das in einer Variablen festhalten? Ich habe im Internet etwas mehr über Anführungszeichen gelesen:
UPTIME=`cat /proc/uptime`
Cool, jetzt habe ich es in einer Variablen. Merke: Auf diese Weise kann man alle möglichen interessanten Dinge in Variablen einlesen. Das muss ich mir in Zukunft merken. LERNEN. Außerdem, was hat es mit diesem /proc-Zeug auf sich? Oh, da steht alles Mögliche drin, zum Beispiel:
cat /proc/cpuinfo
OK, jetzt habe ich also diese große Dezimalzahl. Wie rechne ich das in Tage um, so dass ich Betriebszeiten wie „23,8 Tage“ habe? Außerdem gibt cat /proc/cpuinfo zwei Zahlen zurück. Welche will ich haben? Und wie kann ich das auseinandernehmen, so dass ich nur diese Zahl habe? Ich habe ein bisschen mehr gelesen. Es gibt einige Möglichkeiten, eine Zeichenkette zu zerlegen, aber das erste, worauf ich stoße, ist der Befehl cut. Wie verwende ich den mit einer Zeichenkette? Ich habe einen Artikel über Piping und Umleitung gelesen. Ich sehe, dass die beiden Zahlen durch ein Leerzeichen als Begrenzer getrennt werden, also:
NUMBERIWANT=`echo ${uptime} | cut -d " " -f 1`
Cool. Das muss ich mir merken. Mit diesem Rohr kann ich interessante Dinge anstellen. Ich speichere das geistig ab, zusammen mit dem cut-Befehl, der eines der nützlichsten Kommandozeilen-Tools sein wird, denen ich je begegnet bin.
Nun, wie kann ich das in Tage umwandeln…hm, enttäuschend, Bash hat eine beschissene Mathe-Unterstützung. Hm, dieser Artikel spricht über bc. Ein wenig Experimentieren und:
uptime=`echo "scale=2; $uptime/86400" | bc`
So bc ist das Programm, das zum Rechnen benutzt wird. Das werde ich mir merken müssen. Ich habe in den vorangegangenen Schritten etwas über Backquotes und die Pipe gelernt, also war es offensichtlich, wie man das hier verwenden kann.
Wie kann ich das nun in eine Textdatei ausgeben, die ich als PHP-Include auf der Website verwenden kann (PHP hat auf die gleiche Weise gelernt)?
Ah, Umleitung!
echo $uptime > ./uptime.txt
Und so weiter. Wenn ich mir meine alten Skripte ansehe (einschließlich dieses), ist die Codierung ineffizient und nicht unbedingt so, wie ich es jetzt machen würde. Aber wenn ich diesen Prozess über die Jahre verfolge, verbessern sich meine Fähigkeiten und mein Wissen, und indem ich mich durch schlechte Praktiken in die Enge treibe, lerne ich, wie man Dinge nicht tun sollte. Meine Methoden verbessern sich, so dass die Skripte besser wartbar sind – nicht, indem ich in einem Klassenzimmer sitze oder ein Buch lese, sondern indem ich mich selbst über den Tisch ziehe und daraus lerne.
Hinweis: Ich bin kein professioneller Entwickler. Ich schreibe Skripte hauptsächlich für meine eigenen (hobbymäßigen) Zwecke. Ich weiß, dass Leute mit einem Informatik-Hintergrund Einwände gegen diese Lernmethode haben könnten, aber für mich hat sie bisher gut funktioniert. Und es macht eine Menge Spaß, weil es nicht nur eine alltägliche Übung des Lesens und Auswendiglernens ist, sondern weil ich dabei etwas „herausbekomme“ – nützliche Skripte.
Übrigens – merken Sie sich das, wenn Sie es noch nicht haben. Es ist fantastisch:
Advanced Bash Scripting Guide — das meiste, was ich über Bash weiß, stammt von hier.