Subshell Web Service

2014-12-27

Das folgende Bash-Skript antwortet auf einen HTTP-Request mit der aktuellen Uhrzeit.

Beim Start des Skripts werden 2 Prozesse gestartet:

  1. nc horcht auf Port 8080 auf einen HTTP-Request und leitet diesen an die named Pipe weiter.
  2. Der zweite Prozess liest von der named Pipe und leitet mitsamt HTTP Return Code die aktuelle Zeit an nc weiter.

Die named Pipe in Kombination mit der Subshell des 2. Prozesses ist der Kniff des Skripts damit auch die aktuelle Zeit über nc als HTTP-Response zurück geliefert wird.

#!/bin/bash

if [ ! -p pipe ]; then
    mkfifo pipe
fi

while true; do 
    { 
       read line < pipe        
       echo -e "HTTP/1.1 200 OK\r\n"        
       echo $(date)     
     }  | nc -l 8080 > pipe
done

Eine brauchbare Erklärung zur Subshell ist auf Stackexchange zu finden.


Backup-Medium Erstellen und Booten

2014-12-03

Die folgenden Schritte beschreiben, wie der Inhalt von Gerät /dev/sdX nach /dev/sdY kopiert wird. Die entstandene Linux-Kopie (in diesem Fall Ubuntu) wird im Anschluss Boot-fähig gemacht.

Wozu benötigt man dies? Ein Anwendungsfall ist z.B. ein Backup einer internen Festplatte auf ein externes Medium (z.B. USB-Festplatte). So kann beim Ausfall der internen Festplatte vom externen Medium gebootet werden.

Als erstes ist von einem Live-Medium zu booten, wenn z.B. ein Backup des Betriebssystem erstellt werden soll. Die hier aufgezählten Schritte wurden mit Ubuntu 14.04 ausgeführt, sollten jedoch auch auf andere Linux-Distributionen übertragbar sein. Die oben aufgeführten Geräte /dev/sdX nach /dev/sdY werden hier lediglich als Beispiel verwendet und sind zu ersetzten durch die tatsächlich genutzten. Diese kann man z.B. durch das folgende Kommando ermitteln:

sudo lshw -class disk

Vorbereitung: Partitionen auflisten, um Typ und Größe zu prüfen; was ist die bootbare Systempartition?

sudo fdisk -l
  1. Kopie von Gerät /dev/sdX auf Gerät /dev/sdY erstellen:

    sudo dd if=/dev/sdX of=/dev/sdY bs=1M conv=noerror
    
  2. Mounten der kopierten Systempartition /dev/sdYn (n=Partitionsnummer):

    sudo mount /dev/sdYn /mnt
    
  3. Re-Mount der virtuellen Dateisysteme auf das kopierte System:

    sudo mount --bind /dev  /mnt/dev
    sudo mount --bind /dev/pts  /mnt/dev/pts
    sudo mount --bind /proc /mnt/proc
    sudo mount --bind /sys  /mnt/sys 
    
  4. Nun der Trick – Wechsel des Root-Verzeichnisses auf kopierte Systempartition (öffnet von nun an root-Shell):

    sudo chroot /mnt
    
  5. Dies ermöglicht das erstellen der Grub2 Konfiguration /boot/grub/grub.cfg auf das kopierte System:

    update-grub
    
  6. Grub2 auf dem kopierten Medium installieren:

    grub-install /dev/sdY
    
  7. Grub2 Installation verifizieren:

    grub-install --recheck /dev/sdY
    
  8. Im Anschluss sind noch die Mount-Einträge der Dateien /etc/fstab bzw /etc/mtab zu überprüfen. Es wird empfohlen die logischen Partitionsnamen, die dort eingetragen sind, z.B. /dev/sdYn, durch die entsprechende UUID zu ersetzten. Die UUIDs lassen sich, wie folgt, ermitteln:

    blkid
    
  9. Rechner neu booten (und im Anschluss im Bios das entsprechende Laufwerk für /dev/sdY als Boot-Medium auswählen):

    reboot
    

Subversion-Historie um Dateien bereinigen

2011-11-09

Es kann schon mal vorkommen, dass man versehentlich eine Datei in Subversion eincheckt, die dort einfach nichts verloren hat – zum Beispiel eine Konfigurationsdatei mit Zugangsdaten. Hier kommt man mit dem logischem Löschen anhand des Kommandos svn rm file nicht wirklich weiter, da die Datei in der Historie verbleibt und so für andere weiterhin abrufbar ist. In diesem Fall hilft nur das Exportieren, Filtern und neue Aufsetzen des Subversion-Repositories, wie in den folgenden Schritten beschrieben wird.

Im ersten Schritt wird ein Dump vom bestehenden Repository erstellt.

svnadmin dump /var/svn > svn-repo-dump

Im Anschluss wird der Dump um die gegebenen Dateien, welche nicht mehr in der Historie geführt werden sollen, gefiltert.

svndumpfilter exclude path/to/pwd-file \
                      path/to-another/file \
                      < svn-repo-dump \
                      > svn-repo-dump-filtered

Dann ist das bestehende Repository zu sichern und ein neues unter dem gleichen Pfad anzulegen.

mv /var/svn /var/svn.backup
svnadmin create /var/svn

Zum Schluss wird dann noch der gefilterte Dump in das neu angelegte Repository eingespielt. Fertig.

svnadmin load --force-uuid /var/svn < svn-repo-dump-filtered 

Rekursive Suche nach Klassen in Java-Archiven

2011-08-25

In welchem Java-Archiv war noch einmal die Klasse X? Ist die Klasse Y vielleicht noch in einem anderen JAR vorhanden? Hier kann eine rekursive Suche im Dateisystem helfen indem als kleines Hilfswerkzeug die folgende Shell-Funktion in der Datei ~/.bashrc eingefügt wird.

search_jars() {
    search_dir=$1 
    search_term=$2 
    if [ -z "$search_term" -o -z "$search_dir" ]; 
    then
        echo "usage: search_jars [DIRECTORY] [SEARCH_TERM]"
        return 1
    fi
    echo "Searching JARs which contain classes matching \
        '$search_term' in '$search_dir'"
    find $search_dir -name "*.jar" -type f -exec \
         bash -c 'jar tvf "$1" | grep "$2"; \
             if [ $? == 0 ]; then \
                 echo "Found in JAR $1"; \
             fi' {} {} $search_term \;
}

Das folgende Beispiel ruft search_jars auf der Konsole im aktuellen Verzeichnis auf und findet sämtliche Java Archive, die einen Klassennamen enthalten, welcher mit Locator.class endet.

>search_jars . Locator.class
Searching JARs which contain classes matching 'Locator.class' in directory '.'
  com/sun/xml/bind/validator/DOMLocator.class
  com/sun/xml/bind/validator/Locator.class
  com/sun/xml/bind/validator/SAXLocator.class
Found in JAR ./jaxb1-impl.jar
  javax/xml/bind/ValidationEventLocator.class
Found in JAR ./jaxb-api.jar
  com/sun/tools/xjc/reader/dtd/bindinfo/DOM4JLocator.class
  com/sun/tools/xjc/reader/dtd/bindinfo/DOM4JLocator.class
Found in JAR ./jaxb-xjc.jar

SSH-Login ohne Kennwort in 3 Schritten

2010-11-27

Schritt 1: Generierung des Schlüsselpaares

you@localhost:~$ ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/home/you/.ssh/id_rsa): 
Created directory '/home/you/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/you/.ssh/id_rsa.
Your public key has been saved in /home/you/.ssh/id_rsa.pub.
The key fingerprint is:
27:e7:1f:0c:99:7d:3b:86:cb:39:91:55:5b:0d:e5:20 you@localhost
The key's randomart image is:
+--[ RSA 2048]----+
|            E ooo|
|             . o+|
|               .+|
|           +  .. |
|        S * .o.  |
|         = ooo . |
|          . +.+  |
|           o.= . |
|            =.   |
+-----------------+

Schritt 2: Erzeugung von ~/.ssh auf Remote Host (optional)

you@localhost:~$ ssh remote_user@remote.host 'mkdir -p .ssh'

Schritt 3: Öffentlichen Schlüssel publizieren

you@localhost:~$ cat ~/.ssh/id_rsa.pub | ssh remote_user@remote.host 'cat >> .ssh/authorized_keys'

>> Ältere Einträge