Spezielle Variablen

Es gibt Variablen, die von der Shell gesetzt werden (können), aber vom Nutzer nicht direkt verändert werden können.

  • $$ Prozess-ID der aktuellen Shell
  • $! Prozess-ID des letzten Hintergrund-Prozesses
  • $- für die Shell gesetzte Option
  • $_ Letztes  Argument des vorherigen Kommandos
  • $? Rückgabestatus / Exit-Status
  • $# Anzahl der Parameter
  • $* Alle Parameter
  • $@ Alle Parameter als einzelne Zeichenketten

Mit wget Bilddateien runterladen

Man kann den wichtigen Befehl "wget" dazu verwenden, bestimmte Dateiarten bei einer bestimmten domain runter zu laden (vgl. scraping). Folgendes Beispiel steht für eine Beispielseite - alle Bilder liegen auf der img-Subdomain. Wichtig ist, dass die for-Schleife für die zu scrapende Seite(n) geeignet ist. Nicht alle Seiten weisen eine Struktur auf, bei denen Unterseiten mit 1-10 (o.Ä.) aufgerufen werden!

Ein Beispiel:

for i in {1..9}; do wget -H -c -nd -e robots=off --include-directories=img -r --reject=tn_* --accept=*.jpg,*.jpeg,*.png,*.bmp,*.gif --domains=img.testserver.com --user-agent="Opera/9.00 (Windows NT 5.1; U; en)" "http://testserver.com/archive/tags/realestate/page/${i}"; done


Achtung, es wird in das jeweils aktuelle Verzeichnis gespeichert! Also am besten vorher ein Verzeichnis erstellen, in dieses wechseln und erst dann den obigen Befehl ausführen!

Festplatten synchronisieren mit Linux-Shell

Beispielhaftes Szenario: Ein Verzeichnis auf dem Desktop-Rechner soll mit einer externen Festplatte synchronisiert werden. Ein einfacher copy-Befehl (cp) hätte diverse Nachteile. Vielmehr benutzen wir den Befehl "rsync" um einen Abgleich der Daten zu machen.

Beispiel:
rsync -aP /daten/wichtig /media/##_backupverzeichnis
Die Option "-a" vereint mehrere Optionen und steht für "archive". So werden zB die Verzeichnisse rekursiv abgeglichen, also auch Unterverzeichnisse.

Die Option "-P" sorgt dafür, dass einem der Fortschritt der Operation angezeigt wird. Vor allem bei Gigabyte-großen Kopieraktionen sollte dies aktiviert werden.

Das Verzeichnis /media/... wird oft für angeschlossene USB-Festplatten verwendet (Ubuntu-Linux). Wird von einer USB-Festplatte auf die andere synchronisiert (zB bei Umstieg von 1TB auf 1,5TB Festplatte), so kann es zu folgenden Befehlen kommen, die erst nicht nach einer Sicherung zwischen verschiedenen Festplatten aussieht:
rsync -aP /media/MP3 /media/##_MP3

Shellskript für Liste mit allen AVI/MKV Dateien im jew Verzeichnis

#!/bin/bash
# Liste, um alle avi/mkv-Dateien im aktuellen(!) Verzeichniss
# (+alle Unterverzeichnisse) in eine Liste zu schreiben
# Alternativ könnte man alle Dateien auflisten und diese dann auf ein egrep
# pipen. Dann muss man aber mit einem
# sed-Befehl anschließend mehr entfernen (uA auch viele Leerzeilen!).

#Dateiname festlegen HIER
l="liste.txt"

#Datei löschen
rm $l 2>/dev/null

# Überschrift!
echo "######        Filmliste     #####" >>$l

# So, jetzt noch eine Leerzeile!
printf "\n" >>$l

# avi-Dateien finden, Fehlermeldungen löschen, Bis zum letzten "/" löschen,
# Rest an Datei anhängen.
printf "#### AVI-Dateien #####" >>$l
printf "\n" >>$l
find `pwd` -type f -name *.avi 2>/dev/null | sed 's:.*\/::' >>$l
printf "\n" >>$l
printf "\n" >>$l
printf "#### MKV-Dateien #####" >>$l
printf "\n" >>$l
find `pwd` -type f -name *.mkv 2>/dev/null | sed 's:.*\/::' >>$l

STDOUT, STDERR und STDIN

STDOUT, STDERR und STDIN werden benutzt, um Eingaben und Ausgaben in der Shell umzuleiten. Die Begriffe stehen für "standart output" (STDOUT), "standart error" (STDERR) und "standart input" (STDIN). Per default werden Ausgaben eines shell-Befehls über STDOUT und STDERR auf der Befehlszeile direkt sichtbar ausgegeben.

STDIN kann benutzt werden, um Nutzereingaben aufzunehmen und zu verarbeiten.

In einem shell-skript oder einem Einzeiler werden die obigen, langen Begriffe nicht direkt benutzt, sondern Zahlen-Variablen. Die 1 für STDOUT und die 2 für Fehlermeldungen, also STDERR. Ein Beispiel, was sehr häufig genutzt wird ist der Befehl "2>/dev/null". Damit werden alle Fehlermeldungen (z.B. keine Leserechte in bestimmen Verzeichnissen) in den Müll (a.k.a. /dev/null) geschickt und erscheinen somit nicht auf dem Bildschirm! Sehr nützlich, bitte merken.

Wird keine Nummer angegeben,so geht die shell davon aus, dass man STDOUT (also 1) meint: 
ls -la > inhalt.txt
 Ist das selbe wie:
ls -la 1> inhalt.txt
Möchte man STDOUT in einen file und STDERR in einen anderen file lenken, macht man dies wie folgt:
ls -la 1>inhalt.txt 2>fehlermeldungen.txt
STDOUT und STDERR in einen file zusammen lenken? Kein Problem:
ls -la >inhalt.txt 2>&1
Möchte man allerdings trotz Umleitung in eine Datei eine Ausgabe (zur Kontrolle zB) auf dem Bildschirm sehen, gibt es auch dafür eine Lösung:
ls -la | tee inhalt.txt

Mehr Infos bei skorks.com.

Linux Shell und RegEx Befehle 1

Ich habe eine Datei mit unnötigen Leerzeilen erstellt, eine Wortliste. Ich möchte mit egrep alle Leerzeilen entfernen.

Die Datei heißt "wl" und die Ausgabe erfolgt in die Datei "wl2". Folgende Befehle sind möglich:

egrep -e ^[^$] wl > wl2
oder

cat wl | egrep ^[^$] > wl2

oder in VIM (ein Befehl wird auf die GANZE Zeile angewendet, darum wird :g verwendet):
:g/^$/d
Folgender Befehl würde in VIM nicht wie gewünscht funktionieren, da eine leere Zeile einfach durch eine leere Zeile ersetzt wird...(ergo: keine sichtbare Änderung!):
:%s/^$//

Der zweite Befehl ist komplizierter, aber für manche vielleicht einfacher zu verstehen.

-----------------------------------------------------------------------------

Nachdem alle Leerzeilen entfernt wurden, möchte ich aus der Datei "wl2" alle Leerzeichen entfernen, die am Anfang jeder Zeile stehen. Dies erledigt man am besten (dachte ich!) im VI- bzw. VIM-Editor (Aufruf mit "vim wl2"). Dann wird dort folgender Befehl ausgeführt:

:%s/^ //

Problem: Es werden wirklich nur einzelne Leerzeichen am Anfang einer Zeile gelöscht (aka "Ersetzen durch NICHTS"). Was ist zB mit 2 oder mehr Leerzeichen?

Hier die Lösung mit sed:

sed 's/^[ ]*//' neu.txt

Mit Linux (Ubuntu) eine externe Festplatte formatieren - howto

Ich möchte meine neue Hitachi-1GB-Festplatte mit Ubuntu formatieren (NTFS Format), um sie mit dem WDTV-Live Standalone-Player zu nutzen.

Wichtig: Für folgende Aktionen muss man Administratoren-Rechte (zB mit "su" erlangen) haben!
Ich öffne die shell und überprüfe, welche Festplatten dem System zu Verfügung stehen:

fdisk -l
---------------------------------------------------------------------------
Platte /dev/sda: 250.1 GByte, 250059350016 Byte
255 Köpfe, 63 Sektoren/Spuren, 30401 Zylinder
Einheiten = Zylinder von 16065 × 512 = 8225280 Bytes
Disk identifier: 0xccd464a0

   Gerät  boot.     Anfang        Ende     Blöcke   Id  System
/dev/sda1   *           1        3654    29350723+  83  Linux
/dev/sda2            3655       30401   214845277+   5  Erweiterte
/dev/sda5            3655        5478    14651248+  83  Linux
/dev/sda6            5479       15265    78614046   83  Linux
/dev/sda7           15266       25052    78614046   83  Linux
/dev/sda8           25053       28821    30274461   83  Linux
/dev/sda9           28822       30401    12691318+  82  Linux Swap / Solaris

Platte /dev/sdb: 1000.2 GByte, 1000204886016 Byte
255 Köpfe, 63 Sektoren/Spuren, 121601 Zylinder
Einheiten = Zylinder von 16065 × 512 = 8225280 Bytes
Disk identifier: 0x1348d81d

   Gerät  boot.     Anfang        Ende     Blöcke   Id  System
/dev/sdb1               1      121601   976760001    7  HPFS/NTFS
---------------------------------------------------------------------------

Es werden 2 physiche Festplatten angezeigt. Die zweite möchte ich partitionieren. Das Dateisystem ist schon NTFS, da muss ich eigentlich nichts ändern, da der Hersteller (Hitachi) schon alles richtig eingerichtet hat :)

fdisk /dev/sdb

Ich erstelle eine Primäre Partition, Größe ca 150 GB und als Dateisystem wird HPFS/NTFS ausgewählt (Hexcode 7).
Nun versuche ich diese neue Partition zu mounten:

sudo mount -t ntfs /dev/sdb1 ~/extern

Das schlägt fehl, als nächstes lösche ich alles und erstelle eine neue Partition, diesmal aber als "erweitert".

--------------------------------------------------------------------------

Da alles nicht funktioniert, hier meine abschließende LÖSUNG des PROBLEMS:

Ich installiere gParted, eine graphische Partitionierungsoberfläche für Gnome. Zusätzlich installiere ich NTFSPROGS (apt-get install ntfsprogs), damit man auch ntfs-Partitionen erstellen kann.

Ein Aufruf des Programms gParted erfoglt bei Ubuntu über das Menü SYSTEM -> SYSTMVERWALTUNG -> GParted.

Ergebnis:
--------------------------------------------------
Platte /dev/sdb: 1000.2 GByte, 1000204886016 Byte
255 Köpfe, 63 Sektoren/Spuren, 121601 Zylinder
Einheiten = Zylinder von 16065 × 512 = 8225280 Bytes
Disk identifier: 0x1304581d

   Gerät  boot.     Anfang        Ende     Blöcke   Id  System
/dev/sdb1               1      121601   976760001    5  Erweiterte
/dev/sdb5               1       79222   636350652    7  HPFS/NTFS
/dev/sdb6          107640      121601   112149733+   7  HPFS/NTFS
/dev/sdb7           79223      107639   228259521    7  HPFS/NTFS

-----------------------------------------------------

Es wurde also eine Erweiterte Partition über die kompletten 1000 Gigabyte erstellt. Diese wurde in 3 Logische Partitionen eingeteilt.

Erfolg!