… oder was „JavaScript“ und „Shell-Script“ gemeinsam haben.
Zu beginn muss ich zugeben, dass ich bei meinen ersten Skripten auch nicht auf den Sichtbarkeitsbereich von Variablen (Scope) geachtet habe. Wenn man sich jedoch etwas mit Softwareentwicklung auseinandersetze stellt man schnell fest, dass globale Variablen direkt aus der Hölle kommen und nichts im Quelltext zu suchen haben.
Variablen sind zumindest in der Shell und in JavaScript zunächst global, selbst innerhalb von Funktionen und werden erst durch den Zusatz „var“ bzw. „local“ zur lokalen Variable. In vielen anderen Programmiersprachen erkennt man den Scope einer Variable direkt im Zusammenhang, ist z.B. eine Variable innerhalb einer Methode deklariert, so ist diese nur innerhalb dieser Methode verfügbar. Wird die Variable jedoch innerhalb der Klasse deklariert, so ist diese für die ganze Klasse und somit für alle Ihre Methoden verfügbar.
Es folgen ein paar Beispiele, wo der Inhalt (Title der Beiträge) des RSS-Feeds von “planet.ubuntuusers.de” ausgegeben werden soll.
Um dies selber zu testen, öffne die Verlinkte Datei im Browser (leere Webseite) und öffne die Entwicklertools (F12), schalte die Ansicht auf “Konsole” und lade die Seite neu. Im Quelltext sind ausschließlich globale Variablen verwendet, jedoch funktioniert dieses Script “leider” wie gewünscht. Das Problem mit globalen Variablen ist, dass man den Quelltext dadurch ggf. schwerer lesen kann und diesen nicht wiederverwenden kann. Wenn man z.B. verschiedene Funkionen als unterschiedlichen Skripten zusammenfügt oder zusammen nutzen möchte, welche jedoch ebenfalls globale Variablen nutzen, dann können da sehr eigenartige Ergebnisse bei herauskommen.
In den DevTools von Chrome kann man jetzt den entsprechenden Variablen-Scope sehen. Jedoch ist der Quellcode noch nicht wirklich wiederverwendbar, da wir das zu lösende Problem (also das laden und parsen einer JSON-Datei) nicht auf eine eigene Abstraktionsschicht gebracht haben.
In diesem Beispiel wurde nun die Klasse “PlanetUbuntuuserJsonData” erstellt welche wiederum von der Klasse “JsonData” dessen Eigenschaften (Variablen & Methoden) erbt. Leider ist der Quelltext hierbei von zirka 50 auf zirka 80 Zeilen erhört worden und funktioniert dabei z.B. nicht im IE < 10. (siehe Kommentare im Quelltext)
Dieses Beispiel benötigt zwar die “jQuery”-Bibliothek, welche jedoch bereits entsprechende Funktionalitäten kapselt. Vergleich man diesen Quellcode mit der Vorherigem Version, kann man schnell erkennen, das entschieden weniger Quellcode deutlich besser zu lesen ist. ;-)
In diesem Beispiel sind wieder sehr viele globale Variablen verwendet und wieder funktioniert das entsprechende Skript “leider” trotzdem. Die Funktion “parse_json()” gibt nicht einmal einen Rückgabewert zurück, dafür teilen sich die beiden Funktionen die Variablen. Und im Grunde könnte man den ganzen Quelltext auch einfach ohne Funktionen untereinander schreiben, dies hätte den selben Effekt.
Die entsprechende Ausgabe ist bereits im Vorherigen Bild zu sehen. Bei Shell-Skripten kommt es seltener vor, dass man dessen Funktionalität wirklich wiederverwenden möchte, jedoch ist der Quelltext deutlich besser zu lesen, wenn man entsprechende Rückgabewerte und Übergabeparameter verwendet.
Vor einiger Zeit habe ich bereits einen Blog-Post über meine “.dotfiles” geschrieben, jedoch habe ich mich damals mehr auf die Installation beschränkt und habe keine Beispiele gezeigt, so dass man den Vorteil der .dotfiles nur schwer erfassen konnte.
Außerdem benötigt man ggf. nur einige Funktionen oder Dateien um sein System an an seine Bedürfnisse anzupassen. Auf der Webseite GitHub ❤ ~/ gibt es sehr gute .dotfiles Sammlungen, welche man einfach “forken” und anpassen und nutzen kann.
Wenn man sich direkt über die Konsole einloggt (ohne GUI) oder remote über ssh, dann wird die Datei: “~/.bash_profile” (bash) bzw. “~/.zprofile” (zsh) ausgeführt, um Ihre Shell vor der ersten Eingabeaufforderung zu konfigurieren.
Wenn man jedoch bereits angemeldet ist und ein neues Terminalfenster z.B. in Gnome oder KDE öffnet, dann wird die “~/.bashrc” bzw. “~/.zshrc”-Datei ausgeführt. Außerdem wird die “.[bash|z]rc” auch ausgeführt, wenn man eine neue Bash-Instanze via “/bin/bash” in einem Terminal ausführt. Um zu verhindern, dass unsere Einstellungen automatisierte Skripte negativ beeinflussen, führen wir die folgenden Anpassungen nur bei interaktiven Konsolen aus.
In meiner “.bashrc”-Datei ist nicht viel zu sehen, da diese Datei auf die “.bash_profile”-Datei zugreift, so dass man bei Änderungen nur eine Datei bearbeiten muss. In “.bash_profile#L19” werden wiederum andere Dateien geladen, so dass wir die selben “Funktionen” und “Aliases” sowohl in der “Bash” als auch in der “Z-Shell” verwenden können.
In dieser Datei kann man Einstellungen für meine .dotfiles vornehmen. Wenn du z.B. deinen Standard-User-Namen in der Variable “CONFIG_DEFAULT_USER” hinterlegst, wird diese nicht mehr in der Shell-Prompt angezeigt.
.path
In dieser Datei kannst du Pfade zu deinen Ausführbaren Dateien einfügen, so dass du diese ohne Angabe des Pfades ausführen kannst.
Diese Datei ist nicht im öffentlichen Repository und ist via “.gitignore” aus git verbannt, da es vertrauliche Informationen enthalten kann. z.B.: export PATH=”$HOME/utils:$PATH”
Variablen in Shell-Scriptes verhalten sich so ähnlich wie in JavaScript. Variablen sind Standardmäßig “global”, dass heißt selbst Variable innerhalb einer Funktion sind anschließend auch außerhalb der Funktion verfügbar. Daher verwenden wir “local” innerhalb von Funktionen, für Variablen welche nur innerhalb der Funktion zur Verfügung steht sollen. Außerdem können wir Variablen via “export” exportieren, so dass diese nicht nur zur Ausführungszeit, sondern anschließend ebenfalls allen Kindprozessen als Umgebungsvariable zur Verfügung stehen.
Überlegungen: In der “normalen” Programmierung nutzt man lowerCamelCase für normale Variablen / Funktionen und Methoden, jedoch sind eigentlich alle Funktionen in der Shell lowercase z.B.: whoami, updatedb, killall. Ich mich dafür entschieden mich bei neuen Funktionen und Aliases an einem Original-Befehl zu orientieren, so dass man diese nicht neu lernen muss, sondern diese via [Tabulator] nutzen kann.
.extra
Auch diese Datei ist nicht im öffentlichen Repository und ist via “.gitignore” aus git verbannt, da es vertrauliche Informationen enthalten kann. Hier kann man alle zuvor gesetzten Variablen, Einstellungen, Funktionen überschreiben oder ergänzen.
Alle alten Version der Unix-Shell “bash” enthalten eine kritische Sicherheitslücke (CVE-2014-6271), so dass man Befehle z.B. über CGI-Skripte oder via DHCP ausführen kann. Ggf. benötigt nun dein Handy (z.B. CyanogenMod), dein Router oder deinen Mac / Linux / BSD und so weiter Software-Updates.
Teste dein System:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
vulnerable
this is a test
Nachdem man die aktuellen Updates eingespielt hat (z.B. via aptitude) dann sollte die Ausgabe folgendermaßen aussehen.
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
bash: warning: x: ignoring function definition attempt bash: error importing function definition for `x’ this is a test
Jede neue Bash-Instanz wird nun beim Start die Funktion “foo” registrieren, so dass man diese Ausführen kann. Wenn man nun jedoch eine Funktion exportiert, führt die Bash den nächsten Befehl ebenfalls aus, da der String der “() {” nicht korrekt geparst wird. Damit können wir nun Befehle ausführen, indem wir bestimmte Strings (Funktionsdefinitionen) an z.B. ein CGI-Skript übergeben.
Habe soeben folgende Funktionen zu meinen dotfiles hinzugefügt, um einen freien lokalen Port zu finden. Diese werden wiederum verwendet, um z.B. die “phpserver“-Funktion auszuführen.
# -------------------------------------------------------------------
# netstat_used_local_ports: get used tcp-ports
netstat_used_local_ports()
{
netstat -atn | awk '{printf "%s\n%s\n", $4, $4}' | grep -oE '[0-9]*$' | sort -n | uniq
}
# -------------------------------------------------------------------
# netstat_free_local_port: get one free tcp-port
netstat_free_local_port()
{
read lowerPort upperPort < /proc/sys/net/ipv4/ip_local_port_range
# create a local array of used ports
local all_used_ports=($(netstat_used_local_ports))
for port in $(seq $lowerPort $upperPort); do
for used_port in "${all_used_ports[@]}"; do
if [ $used_port -eq $port ]; then
continue
else
echo $port
return 0
fi
done
done
}
Ich habe schon vor einiger Zeit über die “.bashrc” berichtet und hier die Installation meiner dotfiles [~/.*] vorgestellt.
Heute möchte ich an einigen Bildern zeigen wie die Bash aussieht nachdem man die bereits erwähnten dotfiles installiert und wie man diese nach seinen Wünschen anpasst.
1.) der Code
.bashrc: Dies ist die Konfigurationsdatei der Bash, diese wird bei jedem Aufruf einer interaktiven Shell ausgeführt. In meiner .bashrc stehen zunächst einmal ein paar Informationen, wovon ich hier nur die entsprechenden Links nennen möchte, welche man sich einmal anschauen sollte:
.bash_profile: Diese Datei hat die selbe Aufgabe wie die .bashrc, wird jedoch “eigentlich” nur für Login-Shells aufgerufen. In diesem Fall wird die Datei jedoch auch für interaktive Shells verwende, da wir diese in der .bashrc inkludiert haben.
for file in ~/.{path,colors,icons,exports,aliases,bash_complete,functions,extra,bash_prompt};do [ -r "$file"]&&[ -f "$file"]&&source"$file"
done
unset file
In dieser Datei werden wiederum andere Shell-Konfigurationen geladen (siehe vorheriges Code-Beispiel), welche auch von anderen Shells (z.B.: der zsh) genutzt werden können.
Desweiteren werden einige Einstellungen in einer zweiten for-Schleife ausgeführt. Andere Einstellungen sind näher beschrieben bzw. nur für nicht root-User geeignet und werden daher einzeln ausgeführt.
.bash_prompt: Wie wir im vorherigem Code-Ausschnitt sehen konnten, wird diese Datei zum Schluss geladen, so dass wir zuvor definierte Funktionen und Variablen verwenden können.
# Local or SSH session?
local remote=""
[ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] && remote=1
Wir prüfen, ob es sich hier um ein lokales Terminal oder um eine SSH Verbindung handelt, so dass wir den Hostnamen nur anzeigen, wenn dieser auch benötigt wird.
# set the user-color
local user_color=$COLOR_LIGHT_GREEN # user's color
[ $UID -eq "0" ] && user_color=$COLOR_RED # root's color
Root-User bekommen in der Prompt einen Roten-Usernamen angezeigt.
PS: die User-ID (UID) ist in der passwd zu finden: “cat /etc/passwd”
# set the user
local user="\u"
Die Zeichenkette “\u” wird beim Aufruf der Bash-Prompt in den entsprechenden Usernamen umgewandelt.
PS: hier gibt es eine Übersicht über weiter Zeichenketten, welche von der Bash-Prompt verarbeitet werden können z.B. die Uhrzeit
# set the hostname inside SSH session
local host=""
[ -n "$remote" ] && host="\[$COLOR_LIGHT_GREEN\]${ICON_FOR_AT}\h"
Wie bereits erwähnt zeigen wir den Hostnamen (“\h”) nur an, wenn es sich um eine Remote-Verbindung handelt.
if [[ -n $remote ]] && [[ $COLORTERM = gnome-* && $TERM = xterm ]] && infocmp gnome-256color >/dev/null 2>&1; then
export TERM='gnome-256color'
elif infocmp xterm-256color >/dev/null 2>&1; then
export TERM='xterm-256color'
fi
256 Farben in der lokalen Shell verwenden.
# INFO: Text (commands) inside \[...\] does not impact line length calculation which fixes stange bug when looking through the history
# $? is a status of last command, should be processed every time prompt prints
Da der Bash-Prompt bestemmte Zeichen nicht mag und wir davon einige in der bereits inkludierten “.colors“-Datei verwendet haben, müssen wir diese Variablen nun hier escapen.
Der Prompt wird in der Variable PS1 (“echo $PS1”) gespeichert und nach jedem Befehl auf der Kommandozeile neu aufgerufen / ausgeführt, daher rufen wir in der Variable wiederum Funktionen auf, so dass diese Funktionen ebenfalls erneut ausgeführt werden.
PS: “$?” muss als erstes ausgeführt werden, da dieser Befehl den Rückgabewert des letzten Kommandos zurückliefert
2.) Beispiele
– Root-User wird rot gekennzeichnet
– “✗” anzeigen, wenn der letzte Befehl nicht korrekte funktioniert hat
– Anzeigen des Hostnamens nur bei Remoteverbindungen
– Repository-Branch (git, svn) anzeigen
– Repository-Status anzeigen (! anfügen, wenn etwas nicht eingecheckt ist)
An dieser Stelle wollte ich einmal notieren wie ich in der täglichen Arbeit mit z.B. “grep” oder “find” etc. umgehe, um möglichst schnell in Verzeichnissen und Dateien zu suchen oder Text zu ersetzten.
Ich werde hier nicht alle Möglichkeiten der entsprechenden Befehle nennen können, daher beschränke ich mich auf das, was ich wirklich verwende. Falls du dich weiter in der Thematik einlesen möchtest, empfehle ich gerne den “man”-Befehl oder wie andere es ausdrücken RTFM!
Falls dir die Begriffe tail, cat, less nicht viel sagen, dann klick hier!!!
grep:
global regular expression print -> durchsucht Dateien und Verzeichnisse via RegEx bzw. nach Strings
Kurzform
Langform
Beschreibung
-H
--with-filename
gibt den Dateinamen vor jedem Treffer aus.
-i
--ignore-case
unterscheide nicht zwischen Groß- und Kleinschreibung.
-n
--line-number
gibt die Zeilennummer vor jedem Treffer aus.
-R
-r
--recursive
liest alle Dateien unter jedem Verzeichnis rekursiv.
-v
--invert-match
Invertiert die Suche und liefert alle Zeilen die nicht auf das gesuchte Muster passen.
z.B.:
grep -rHn test ~/php/
-> sucht im Verzeichnis “php”, welches sich wiederum im Home-Verzeichnis [~] befindet nach dem String “test”
PS: hier der selbe Befehl, jedoch eingeschränkt auf php-Dateien
grep -Hn test ~/php/**/*.php
Info: wenn man “git” im Einsatz hat, sollte man “git grep” verwenden ;)
ack:
Ack hat die selbe Aufgabe wie “grep” ist jedoch auf Entwickler zugeschnitten, so sucht “ack” im Standardmäßig rekursiv, ignoriert Binärdaten und Verzeichnisse von Versionkontrollsystemen (.svn, .git, etc.)
PS: unter Debian / Ubuntu findet man das entsprechende Paket unter “ack-grep”
find:
ist bei der Suche nach Dateien behilflich (“Alles ist eine Datei”)
Suchkriterien für find
Kriterium
Beschreibung
-name Datei
Es wird nach Dateien mit dem Namen “Datei” gesucht. Sollen bei der Suche Platzhalter Verwendung finden, so muss der ganze Ausdruck in Anführungszeichen gestellt werden, zum Beispiel
-name "*.txt"
-iname Datei
Es wird nach Dateien mit dem Namen “Datei” – ohne Beachtung der Groß und Kleinschreibung – gesucht.
-type f
Es wird nur nach regulären Dateien gesucht.
-type d
Es wird nur nach Verzeichnissen gesucht.
find -size +10M -20M -exec ls -lah {} \;
-> sucht alle Dateien welche eine Dateigröße zwischen 10 – 20 MB haben und zeigt diese an
WARNING: der “exec”-Parameter kann auch für jeden anderen Befehl auf die Ergebnismenge von “find” ausführen, dabei sollte man jedoch bei dem “rm”-Befehl besonders vorsichtig sein. Und ggf. kann man sich safe-rm anschauen. ;)
“sudo updatedb” nicht vergessen und schon kann man sehr schnell nach Dateien suchen, da die Dateien nicht im Filesystem, sondern in einer Datenbank (updatedb) gesucht werden.
z.B.:
locate Download | grep home
sed:
Es handelt sich hier um einen “nicht-interaktiver Texteditor” was eigentlich nur bedeutet, dass man damit String verarbeite kann. Zum Bespiel kann man ein bestimmtes Wort in einer Datei durch ein anderes ersetzten.
# WARNING -> replace: changes multiple files at once
replace()
{
if [ $3 ]; then
find $1 -type f -exec sed -i 's/$2/$3/g' {} \;
else
echo "Missing argument"
fi
}
replace *.php alt neu
-> dieser Befehl such im aktuellen (+ Unterverzeichnisse) nach Dateien, welche auf “.php” enden und ersetzt darin “alt” gegen “neu”
Dabei ist besonders praktisch, dass man diese Funktionalität auch im “vim” verwenden kann indem man z.B. folgendes eingibt …
:%s/alt/neu/g
diff:
Wie der Name schon vermuten lässt, kann man hiermit Dateien vergleichen. z.B.:
diff -u --ignore-all-space -r old/ new/
-> vergleicht alle Dateien rekursiv (-r) vom Verzeichnis “old/” und “new/” und ignoriert dabei Änderungen vom Leerräumen z.B. Leerzeichen oder Zeilenumbrüche (\r <-> \r\n)
Info: wenn man “git” im Einsatz hat, sollte man “git diff” verwenden ;)
wc:
word count kann Wörtern, Zeichen und Bytes (man ahnt es bereits) zählen. z.B.:
Habe meine dotfiles (Dateien im Home-Verzeichnis, welche mit einem “.” beginnen) mit anderen Quellen angereichert und diese auf github veröffentlicht. Wer möchte kann diese Einstellungen, Aliase, Funktionen für die “Linux-Shell” verwenden oder auch verbessern, indem man einen entsprechenden Fork von dem Projekt erstellt.
cd ~ && git clone https://github.com/voku/dotfiles.git && cd dotfiles && ./bootstrap.sh
… wenn gewünscht kann man mit diesem kleinen Skript entsprechende ggf. benötigte Pakete nachinstallieren:
./firstInstall.sh
Update:
./bootstrap.sh
Einstellungen:
Die Datei “~/.config_dotfiles” beinhaltet einige Einstellungen für die entsprechenden dotfiles. Wenn diese Datei nicht existiert wird diese automatisch beim ausführen der “bootstrap.sh”-Datei erzeugt.
Die Plugins sind von “bash-it“, “oh-my-zsh” und eigenen eigenen Anpassungen zusammengefügt. Außerdem wurden Plugins welche allgemeingültig sind in die globalen “.aliases” und “.functions” ausgelagert.
Wenn die Datei “~/.extra” existiert, wird diese zusammen mit den anderen Dateien verarbeitet. Man kann diese nutzen, um benutzerdefinierte Befehle ausführen zu lassen.
In diesem Blog-Post stelle ich kurz mein kleines Shell-Skript vor, mit dem man sein Ubuntu 11.04 einrichten bzw. optimieren kann. Wenn jemandem noch ein Feature fehlt, kann dies angepasst werden. Zudem habe ich im Quelltext an den meisten Stellen Kommentare hinterlassen, sodass man gleich noch etwas über die shell lernen kann … :-)
[stextbox id=”info”]Über konstruktive Kritik und / oder Verbesserungen würde ich mich freuen.[/stextbox]
Ich habe schon einige kleine Blog-Beiträge zum Thema “Shell / Bash” geschrieben und werde versuchen diese Blog-Beiträge zu einer hoffentlich umfassenden Einführung in das Thema Shell zusammenfassen… :-)
Was ist eine Shell?
Die Shell ist die Eingabe-Schnittstelle zwischen Computer und Benutzer, welche bei normaler Systemkonfiguration nach dem erfolgreichem Login eines Benutzers gestartet wird, so dass man auf dieser Kommandozeile die Möglichkeit hat weitere Programme zu starten. Die Shell könnte man somit aus Arbeitsumgebung bezeichnen, von wo aus der PC gesteuert werden kann bzw. Dateien bearbeitet werden können. Es gibt unterschiedliche Arten von Shell’s, wer ein modernes Linux-Betriebssystem (Debian, Ubuntu…) installiert, landet meistens in der sogenannten “bash“, darauf gehe ich jedoch gleich genauer ein. Die eingegebenen Texteingaben werden von der Shell interpretiert und ausgeführt, daher spricht man bei der Shell auch von einem Kommandozeileninterpreter (command-line interpreter, CLI).
Begrifflichkeiten!?
In Verbindung mit dem Begriff Shell hört man auch immer wieder folgendes …
Konsole: In ihrem ursprünglicher Definition war die Konsole ein Terminal, mit dem der Systemoperator die Systemfunktionen steuern konnte… heute wird der Begriff jedoch ebenfalls für “Terminalemulation” verwendet, zudem heißt die grafischen Terminalemulationen unter KDE “Konsole“.
Virtuelle Konsole: Die meisten Linux-Systeme kommen standardmäßig mit einigen virtuellen Konsolen daher, welche man über <Strg> + <Alt> + <F1> bis <F6> erreichen kann. Mittels <Strg> + <Alt> + <F7> wird der Desktop und somit die graphischen Oberfläche wieder angezeigt.
Terminal: Ein Terminal ist ein Computer, der den Zugriff auf einen entfernten Rechner erhält und die meisten Rechenoperationen somit nicht selber durchführt. (Terminal-PCs) Der Begriff “Terminal” wird heute jedoch auch als Abkürzung für “Terminalemulation” verwendet.
Terminalemulation: Mit einer Terminalemulation wird eine textorientierte Ein- und Ausgabeschnittstelle, ein Terminal emuliert, so dass man mehrer Instanzen eines Terminals auf dem Desktop zur Verfügung hat.
Wie bereits erwähnt kann man zum einen die virtuelle Konsolen, die mit tty bezeichnet werden per Tastenkombination erreichen. Die Abkürzung tty stammt von dem englischen Wort Teletype und wurde historisch bedingt von Unix übernommen. Mittels …
<Strg> + <Alt> + <F1>
… gelangt man in die erste der tty-Konsolen, in diesem Fall tty1.
Hinweis: Hat man eine grafische Oberfläche (Desktop) installiert, so befindet sich dieser standardmäßig auf tty7. Dieser Wert ist jedoch Variabel und kann umverlegt werden. Wer die Maus in einer solchen virtuellen Konsole verwenden will, sollte sich das Programm “gpm” anschauen / installieren.
Hat man sich einmal an die Desktop-Oberfläche gewöhnt, erscheinen einem diese virtuelle Konsolen meist wenig komfortabel, daher gibt es einige Programme (Terminalemulation) welche den Funktionsumfang erheblich erweitern.
KDE – Konsole
KDE-Nutzern steht das bereits erwähnte Programm “Konsole” zur Verfügung, wobei sich der Kreis der Begrifflichkeiten hier schließt und die Verwirrung bei so manchen gerade erst einsetzt. ;-) Lässt man dies außer Acht ist dieses Terminal(emulation) sehr gut. Das Programm unterstützt Tabs, Transparenz, verschiedenste Farbschema, unterschiedliche Schriften und man kann Profile anlegen.
konsole
Gnome – Terminal
Gnome-Nutzer verfügen von Haus aus über ein Programm mit dem Namen “Gnome-Terminal”. Ich persönlich bevorzuge dieses Programm, wobei dies wahrscheinlich eine Übungssache ist…
TASTENKÜRZEL
BEDEUTUNG
<Strg> + <Umschalttaste> + t
öffnet einen neuen Tab
<Strg> + d
schließt einen Tab
<Strg> + Bild rauf
öffnet nächsten Tab (rechts) bzw. den ersten
<Strg> + Bild runter
öffnet vorherigen Tab (links) bzw. den letzen
<Strg> + <Umschalttaste> + Bild rauf
verschiebt einen Tab nach rechts
<Strg> + <Umschalttaste> + Bild unter
verschiebt einen Tab nach links
Hinweis: Wer das Terminal immer Griffbereit haben möchte, sollte sich einmal “guake” anschauen … ;-)
gnome_terminal
Xterm
Xterm ist Bestandteil des X.org Projekts und war lange Zeit das Standardterminal für Linuxsysteme mit grafischer Oberfläche.
CLI Companion
Wer die Linux-Befehle noch lernen möchte oder sich einige komplizierte Behle öfter benötigt, kann sich auch dieses Terminal anschauen. -> cli-companion-die-gui-in-der-konsole
CLICompanion
Terminator
“Terminator ist ein in Python geschriebener Terminal-Emulator für die Desktop-Umgebung GNOME, der es ermöglicht mehrere Terminals innerhalb eines Fensters bzw. einzelner Tabs zu benutzen und mittels Tastatur-Kürzeln zwischen diesen zu wechseln. So kann man ohne Tabs und ohne weitere Terminalfenster mehrere Shells zur selben Zeit offen haben.” – http://wiki.ubuntuusers.de/Terminator
terminator_split_example
Wenn man seine Standard-Terminal ändern möchte, kann man dies mit dem Alternativen-System bewerkstelligen…
Wenn man sich ein wenig näher mit dem Thema beschäftigt, stellt man schnell fest, dass es eine Menge Alternative Shells gibt. Ich beschränke mich einfach mal auf die (heutige) Standard-Shell die bash und einer Alternative der zsh (Z-Shell)
Bourne Again Shell (bash)
Die Bourne Again Shell ist die Standard-Shell der meisten Linux-Distributionen. Die Shell beherrscht die Features der Borune- Korn- und C-Shell. Redet jemand von einer Shell, spricht man meistens von Bash. Um das volle Potenzial der Bash zu nutzen sollte man sich “.bashrc“-Datei anschauen und an seine Bedürfnisse anpassen, für den Anfang sollte meine Datei als Vorlage genügen. -> bashrc
Z-Shell (zsh)
Die Zsh kann man als eine Zusammenstellung aller Verbesserungen und Features aus der bash, der csh und der tcsh betrachten.
Zu einigen ihrer Features zählen:
eine frei programmierbare Wortvervollständigung (TAB-Completion)
die Möglichkeit, die History aus anderen – gleichzeitig laufenden – Shells zu nutzen
Rechtschreibüberprüfung
nahezu vollständige Kompatibilität zur bash, ksh und tcsh
Bei der Z-Shell kann hat man noch viel mehr Einstellungsmöglichkeiten, welche einem Anfangs ggf. überfordern können, daher auch hier meine “.zshrc“-Datei als Vorlage. -> zshrc
Z-Shell installieren:
sudo aptitude install zsh
Z-Shell ausprobieren:
zsh
Standardmäßig die Z-Shell verwenden:
sudo chsh -s /usr/bin/zsh `whoami`
Probieren geht über studieren…
… was ist damit sagen will, wer einmal die Vorteile der Shell erkannt hat und einige Befehle kennt, wird die Shell lieben lernen!
Linux-Dateipfade einigermaßen kennen
Auch wenn in der Shell meist angezeigt wird in welchem Verzeichnis man sich gerade befindet, kann es seht hilfreich sein, wenn man ungefähr weiß wo sich was bei Linux befindet! -> http://wiki.ubuntuusers.de/Verzeichnisstruktur
Verzeichnis
Bedeutung
~ Windows
/
Wurzelverzeichnis
C:\
/boot
Bootloader
C:\
/etc
Systemkonfiguration
registry,
C:\WINDOWS\*.ini
/bin
Systemprogramme für Benutzer
C:\WINDOWS\,C:\WINDOWS\COMMAND\
/sbin
Systemprogramme und -dienste für Admins
/lib
Systembibliotheken und Treiber
C:\WINDOWS\SYSTEM32\
/tmp
Temporäre Dateien
C:\WINDOWS\TEMP\
/usr
(“Unix System Resources”)
/usr/bin
Programme für Benutzer
C:\Programme\*\
/usr/sbin
Programme und Dienste für Admins
/usr/lib
Bibliotheken
/home
Heimatverzeichnisse
C:\Dokumente und Einstellungen\
/home/user
Heimatverzeichnis des Benutzers user
/root
Heimatverzeichnis des Benutzers root
/var
Daten von Diensten
/var/log
Systemprotokolle
/media
Wechseldatenträger, z.B. USB-Stick
/media/cdrom
CD-ROM
A:\, D:\, E:\,...
Beim Login in die Shell, landet man meistens in seinem eigenen home-Verzeichnis (z.B.: /home/lars/). Im “Prompt” (dem Text vor der Eingabeaufforderung, in der Shell) könnte nun so etwas angezeigt werden “lars@ubuntu:~$“.
lars ist hier der User-Name, ubuntu der Name des PCs und das ~ (Tilde-Zeichen) steht als Abkürzung und Synonym für das Homeverzeichnis, in welchem wir uns gerade befinden, dies kannst du gleich durch die Eingabe des Befehl “pwd” (print working directory) überprüfen. ;-)
Groß- und Kleinschreibung beachten
Anders als bei Windows unterscheidet Linux Groß- und Kleinschreibung, hier einige Beispiele zur Verdeutlichung …
… anzeigen lassen, welche Dateien / Verzeichnisse im aktuellen Verzeichnis erstellt wurden. Mittels “rm” bzw. “rmdir” kannst du diese Dateien wieder löschen. Falls du versehentlich z.B.: “touch ./–help” ausführst und somit eine leere Datei mit dem Namen-“–help” erstellt hast, kannst du diese mittels “rm ./–help” wieder entfernen.
Der Befehl “man” (z.B.: man mkdir) zeigt eine ausführliche Hilfe zum angegebenen Befehl an und “apropos” (z.B.: apropos mkdir) zeigt dessen Funktion schnell an… zudem kann man hinter den Befehlen auch “–help” (mkdir –help) schreiben
Achtung
Achtung: Vorsicht der Befehl “rm -r” löscht rekursiv, am Anfang sollte man diesen Parameter ggf. mit -i kombinieren, so dass vor dem löschen einer Datei noch einmal nachgefragt wird, ob diese wirklich gelöscht werden soll. (z.B.: rm -ri lall/) -> safe-rm can save your life
Die Navigation
Ebenfalls ein sehr großes Themenfeld ist die Navigation in der Shell, angefangen von der Navigation durch die Verzeichnisse / Dateien … über die Verwendung der History (bereits eingegebene Befehle in der Shell) … bis hin zur Navigation innerhalb der Shell.
Navigation in Verzeichnissen
Befehl
BEDEUTUNG
cd ..
wechselt ein Verzeichnis nach oben
cd ../..
wechselt zwei Verzeichnise nach oben
cd ~
wechselt in dein home-Verzeichnis
TAB
durch das drücken der Tabulator-Taste, wird deine Eingabe vervollständigt -> ggf. 2x hintereinander TAB drücken !!!
».«
jedes Verzeichnis enthält eine Referenz auf sich selbst, diesen Punkt benötigt man vor allem,wenn man eine ausführbare Datei starten möchte… (z.b: cd /bin/; ./bash;)
pwd
zeigt an wo du dich befindest
Durch das drücken der TAB-Taste kann man sich viel Tipparbeit ersparen… :-)
Navigation in der Shell
BEFEHL / Tastenkürzel
BEDEUTUNG
<Strg> + d
Logout aus der Shell (logout bzw. exit)
<Strg> + c
laufender Prozesse (im Vordergrund) wird beendet
<Strg> + l
räumt die Ausgabe auf (clear)
fc -l
zeigt die letzten Befehle in einer Liste an
Pfeiltasten (noch oben / unten)
letzte Befehle durchblättern
Pfeiltasten (noch rechts / links)
Cursor auf der Konsole (rechts / links) bewegen
<Strg> + r
sucht einen Befehl in der Bash-History (mehrmaliges drücken von Strg+r geht weiter in der History zurück)
Alt + .
schreibt den letzten Parameter des letzen Befehls auf die Konsole
!$
schreibt den letzten Parameter des letzen Befehls auf die Konsole (Alt + .)
!!
führt den letzten Befehl noch einmal aus
!string
startet den letzten Befehl, der mit sting anfängt
!?string
startet den letzten Befehl, der string enthält
^sting1^string2
wiederholt den letzten Befehl, wobei sting1 doch string2 ersetzt wird
<Strg> + a
Cursor am Anfang der Zeile
<Strg> + e
Cursor am Ende der Zeile
<Strg> + w
schneidet das letzte Wort aus
<Strg> + u
scheidet alles vor dem Cursor aus
<Strg> + k
scheidet alles hinter dem Cursor aus
<Strg> + y
fügt die zuletzt ausgeschnittenen Daten ein
PS: wie bereits erwähnt entfaltet die Shell ihr volles Potenzial erst, wenn man diese ein wenig an seine Wünsche anpasst, daher hier noch einmal der Verweiß auf die .bashrc und .zshrc …
Kommandos hintereinander ausführen
Wie bereits kurz zuvor gezeigt, kann man Befehle auch hintereinander ausführen… z.B.:
cd /bin/; ./bash;
Hier werden die Befehle “cd /bin/” und “./bash” einfach nacheinander ausgeführt. Wenn man den zweiten Befehl jedoch nur ausführen möchte, wenn der erste Befehl ohne Probleme funktioniert hat, kann man && zwischen den beiden Befehlen verwenden… z.B.:
cd /bin_lall/ && ./bash;
Und wenn man den zweiten Befehl nur ausführen möchte, wenn der erste Befehl nicht funktioniert hat, nimmt man “||“… z.B.:
cd /bin_lall/ || echo "ggf. existiert /bin_lall nicht";
PS: Natürlich muss man nicht jedesmal in das Verzeichnis /bin wechseln, wenn man ein Programm aus diesem Verzeichnis öffnen möchte, dazu wird in der Shell die Variable “$PATH” verwendet. z.B.:
Wer direkt in der Shell Dateien verändern möchte, sollte sich den “vim”-Editor anschauen, wie die Shell ist dieser Editor gewöhnungsbedürftig aber man gewinnt Ihn mit der Zeit lieb… ;-) In diesem HowTo habe ich versucht die wichtigsten Funktionen von vim zusammenzufassen. Und hier noch eine Schnellübersicht:
BEFEHL / TASTENKÜRZEL
BEDEUTUNG
i
Text einfügen, vor dem Cursor
R
Text ab Cursor-Position überschreiben
<Strg> + v
Bereich markieren
<ESC>
Bearbeitungsmodus beenden
y
kopieren
p
einfügen
:q
vi/vim beenden
:w
Datei speichern
vi-vim-cheat-sheet_de_layout
Es gibt unter Linux noch etliche Programme, welche einem beim bearbeiten von Dateien hilfreich sein können z.B.: sed
sed -i 's/Ubuntu/Windows/g' test.txt
Dieser Befehl ersetzt das Wort “Ubuntu” durch “Windows” in der ganzen Datei “test.txt” im aktuellen Verzeichnis. Weitere Infos zu sed findest du hier -> streameditor-sed und hier noch ein alter Beitrag zum Thema -> Dateien-in-der-shell-bearbeiten
Programme im Hintergrund verschieben
Man kann Programme und Befehle auch im Hintergrund ausführen bzw. diese in den Hintergrund verschieben…
kommando1 und kommando2 wurden beide im Hintergrund ausgeführt, dann wurde kommando2 mittels dem Befehl “fg” wieder in den Vordergrund geholt. Wenn man kommando2 wieder in den Hintergrund verschieben möchte drücken wir: <Strg> + z
In order to optimize the website and to continuously improve it, this site uses cookies. By continuing to use the website, you consent to the use of cookies.