Ich wollte nur [...] und dann ist das Universum explodiert.

Projects
Books
Archive
About









    Permalink
  1. Loading | Eine Bash-Progress-Bar

    Für ein kleines Projekt, an dem ich so nebenher immer etwas schreibe habe ich eine Art Ladebalken gebraucht. Habe ein paar wirklich coole Lösungsansätze gefunden, aber es läuft meistens auf Depencies raus (pv z.B.) oder nicht wirklich mein Anwendungsfall.

    Ich hab mir dann kurzerhand was selber gebastelt. Ich gebe zu ich hätte es auch so gestaltet können das es einfach nur für meinen Use-Case gereicht hätte, aber das erschien mir unsinnig. Wenn ich mich schon einen halben Abend hinsetze, dann können ja evtl. auch mehr Menschen was davon haben. So entstand dann die bash-progress-bar.

    Zu allererst besteht der Ladebalken aus einer while true Schleife. Sollte die Bar in ein Skript einbaut werden wäre die Bedingung dem Skript anzupassen. Ob das jetzt ein test -e auf ein File ist das getouched wird oder eine Art Counter bleibt jedem selbst überlassen.

    $ git clone git://github.com/noqqe/bash-progress-bar.git
    $ cd /bash-progress-bar/
    $ ./loading.sh
    > [            #####       ]

    Alle Parameter sind natürlich anpassbar. Ich habe versucht so gut wie alles anpassbar zu halten. Ich hoffe das ist mir gelungen ;)
    ./loading.sh Groesse Geschwindigkeit Rahmen-Anfang Füllcharacter Rahmen-Ende
    ./loading.sh 50 0.02 [ "######" ]

    Ohne irgendwie ein GIF-File zu erstellen kann ich das jetzt leider schlecht im Blog demonstrieren. Deshalb: ausprobieren :) Mehr Infos auf der Github Page.

    Fragen, Anregungen, Kritik erwünscht!


  2. Permalink
  3. Taskwarrior | The better-task-shell

    Eigentlich wollte ich das Projekt task-shell-ng nennen. Aber so gut ist es dann doch nicht geworden. Stattdessen hat es sich aber den Prefix better verdient ;)

    Als ich vor ca. einem Monat Taskwarrior für mich entdeckt habe, war eigentlich alles gut. Ich hab mich über den integrierten interactive Mode wirklich gefreut. Anfangs. Mit der Zeit habe ich aber festgestellt, dass mich dieses “Ding” fast in den Wahnsinn treibt. Mir persönlich fehlen einfach elementare Features wie einfaches Cursor bewegen nach vorne und zurück. Überhaupt eine History zu haben wäre schon ein enormer Vorteil.

    Ich hab mir dann kurzer Hand selber eine Taskwarrior Shell Variante gebaut, die im großen und ganzen auf einer Bash basiert.

    Features:

    • History vorwärts und rückwärts via Pfeiltasten
    • Cursorbewegung vorwärts und rückwerts in der aktuellen Zeile
    • Alle Kommandos nativ benutzbar ( $ add pri:H pro:Living Miete zahlen )
    • ID’s direkt nutzbar ( $ 34 edit oder $ 12 pri:H )
    • separate Logging Funktion in $HOME/.better-task-shell_history
    • OS Befehle weiterhin nutzbar! ( $ vim /home/user/foobar.txt )
    • Automatische Erkennung von doppelten Aliases
    • Automatische Alias Generierung fuer os-binaries ( $ ls  = task ls  ; os-ls = /bin/ls )
    • Auto-Komplettierung aller Taskwarrior Befehle und definierte Aliase

    Known Bugs:

    • Neu angelegt tasks  können derzeit noch nicht via ID aufgerufen werden.
      $ add Uberweisung einwerfen
      Created Task 45
      $ 45 pri:H
      bash: 45: Kommando nicht gefunden
      Für beim Start bestehende Einträge funktioniert dies allerdings problemlos.
    • Mode -v ist bis jetzt noch nicht benutzbar aber bereits implementiert.

    Das ganze gibts jetzt unter http://github.com/noqqe/better-task-shell

    Usage:

    git clone git@github.com:noqqe/better-task-shell.git
    $ cd better-task-shell
    $ ./better-task-shell


  4. Permalink
  5. ROT13 Verschlüsselung in Bash

    Seit ich meinen neuen Arbeitsweg antrete und täglich ca eine Stunde im Zug verbringe, höre ich umso mehr Podcasts. Besonders gut finde ich http://ulm.ccc.de/dev/radio/. Es ging unter anderem um Algorithmen und Kryptologie im Allgemeinen. Unter anderem eben auch die ROT13 Verschlüsselung.

    Grafik aus Wikipedia unter Public Domain

    Ich habe mir überlegt wie schwierig es wohl sein kann, diesen in Bash zu implementieren. Nach kurzem googlen findet man immer wieder eine kleine wirklich ausgefuchste, trickreiche Zeile:

    $ tr A-Za-z N-ZA-Mn-za-m

    Irgendwie war mir das aber zu langweilig, mir die Arbeit von einem vorgefertigten Binary erledigen zu lassen. Ich wollte es in echtem Bash selbst schreiben. Was ich dann auch getan habe.

    Usage:

    $ ./rot13 "hello world"
    uryyb jbeyq

    $ echo "hello world" | ./rot13
    uryyb jbeyq

    # Verschlüsseln und entschlüsseln hintereinander.
    $ echo "hello world" | ./rot13 | ./rot13
    hello world

    # Zeichentabelle anzeigen
    $ ./rot13 -t

    Sollten Zeichen vorkommen, die sicht nicht im Table befinden, werden diese automatisch erkannt und bleiben unverschlüsselt.

    $ ./rot13 "Ich wollte nur [...] und dann ist das Universum explodiert."
    Ipu jbyygr ahe [...] haq qnaa vfg qnf Uavirefhz rkcybqvreg.

    Genau genommen ist es sogar mehr als nur ROT13. Mit wachsendem Zeichen-Table wächst auch automatisch die Verschiebung der Stellen mit. Es ist also möglich einen eigens definierten Table mit Zeichen anzulegen und diesen zu nutzen. Einzige Bedingung: Es muss eine gerade Anzahl von Zeichen sein.

    Und zum Schluss: Danke an /dev/radio für die erhebliche Verkürzung meiner Zugfahrten :)


  6. Permalink
  7. Shell-Zauberei | Pidgin Chat-Nachrichten zählen

    Code
    cd $HOME/.purple/logs/icq/987654321
    cat */** | grep "^<font" | sed -e 's#.*\ <b>\(.*\):</b>.*#\1#g' | grep -v "^<"|sort | uniq -c | sort -rn

    Hintergrund
    Heute ist der 3. Mai und morgen ist meine Abschlussprüfung zum Fachinformatiker. Natürlich sollte man da andere Sachen machen, als Shell Zeilen zu schreiben, aber mein Kopf fühlt sich von den letzten beiden Wochen, die ich während meines Lernurlaubs damit verbracht habe jegliches während meiner Ausbildung vermitteltes theoretisches Wissen in mich aufzusaugen, sowas von überfüllt an, dass ich während einer Lernpause kurz den Instant-Messenger meiner Wahl angeschmissen habe. Kurz darauf wollte ich wissen, wie viele Nachrichten ich wohl seit Neuinstallation schon erhalten und gesendet habe.

    Funktion
    Die Zeile bewirkt im Grunde nicht anderes als alle Files auszugeben, nach Zeilen zu suchen die auf das Schema passen die dem einer “Nachricht gesendet” Zeile ähneln und sortiert, zählt und sortiert diese wieder. Vorrausgesetzt die Logfiles sind durch Pidgin im HTML Format abgespeichert.

    About: “Ein Byte der Shellzauberei” – Kategorie: http://noqqe.de/archives/category/shell-zauberei


  8. Permalink
  9. Shell-Zauberei | Namensliste in MySQL Datenbank einspeisen

    Code
    for x in $(mysql --batch -u root --password=passw0rd -e "USE rtdb; SELECT DISTINCT id FROM Users;" | grep -v ^id); do mysql -u root --password=passw0rd -e "USE rtdb; UPDATE Users SET Name=\"$(sed -n $(($RANDOM % $(cat Names | wc -l) +1 ))p Names)\" WHERE id=\"$x\" ;" ; done

    Hintergrund
    Wie auch schon beim letzten mal dreht es sich wieder um die Anonymisierung der RequestTracker Datenbank für die ich zur Zeit an einem Statistik Tool arbeite. Diesmal will ich aber nicht die EmailAdressen ändern, sondern die Namen der Benutzer. Da ich diese nicht so einfach generieren lassen kann, habe ich mir aus dem Interweb eine Liste mit Namen besorgt und mit diesen Namen die eingetragenen überschrieben. Jetzt kann ich endlich den Post über das Statistik Tool schreiben und mit Beispielen versehen :)

    Funktion
    Das Ganze läuft wie folgt ab: Für jede ID die ich mittels Datenbank-Verbindung in die For-Schleife einbette, setze ich einen UPDATE Befehl ab, der die Tabelle “Users” und das Feld “Name” aktualisiert. Der Aktualisierungsvorgang passiert aber generisch. Das heisst ich setze den Namen des Users auf einen zufällig ausgewählten neuen Namen aus der Datei “Names”. Das habe ich mit sed -n p FILE gelöst, was sicher auch schöner geht, aber für meine Zwecke hat es ausgereicht.

    About: “Ein Byte der Shellzauberei” – Kategorie: http://noqqe.de/archives/category/shell-zauberei


  10. Permalink
  11. Shell-Zauberei | Emailadressen in MySQL Datenbank anonymisieren

    Code
    for x in $(mysql -u root --password=passw0rd --batch -e "use rtdb; select id from Users" | grep -v ^id); do mysql -u root --password=passw0rd -e "use rtdb; UPDATE Users SET EmailAddress=\"$x@mail.com\" WHERE id=\"$x\"; "; done
    Hintergrund
    Ich arbeite seit kurzem an einem kleinen Statistik Tool für den RequestTracker von Bestpractical. Einem Ticket-System. Um Beispiele für dieses Tool generieren zu können, brauchte ich eine manipulierte Datenbank. Datenschutz. EmailAdressen mit anderem Inhalt überschreiben.

    Funktion
    Im Endeffekt ist es nur eine For-Schleife, die alle User ID’s aus der RequestTracker Datenbank (Table: Users) ausliesst und für jeden gefundenen Eintrag die EmailAdresse auf “ID@mail.com” setzt. So bleiben die Daten auswertbar, sind aber “anonym”.

    About: “Ein Byte der Shellzauberei” – Kategorie: http://noqqe.de/archives/category/shell-zauberei


  12. Permalink
  13. Shell-Zauberei | Eine Einleitung

    Ich möchte mit diesem Post eine kleine Reihe von Blogposts beginnen. Diese Eintragsreihe möchte ich in unbestimmter Länge und Frequenz in meinen Blog etablieren. Der Gedanke zu dieser Aktion, die ich “Ein Byte der Shell-Zauberei” nennen werde, geistert mir schon seit ca. zwei Monaten im Kopf herum.

    Mein Job als Administrator von Debian/Linux Systemen verlangt von mir oftmals Automatisierung und Shell-Scripting in mal größerem und auch kleinerem Umfang. Oft lassen sich derartige Aufgaben sehr leicht in einem Einzeiler/Oneliner auf dem Terminal lösen. Ich mag es, wenn Lösungen schnell und einfach durchzuführen sind, besonders mit Bash. Der Anspruch dieser Aufgaben variiert genauso wie deren Umfang. Die “Zauberei” im Titel der Aktion darf also wahlweise auch etwas ironisch verstanden werden.

    Als mir die Idee kam, dachte ich mir ehrlich gesagt, dass ich für eine solche Reihe wahrscheinlich nicht genügend Kanonenfutter hätte. Sprich, genügend einzeilige Bash Zauberei, die ich im Kontext dieser Reihe posten könnte. Ich beschloss den Gedanken noch nicht sofort zu verwerfen und stattdessen ein paar dieser Einzeiler zu speichern und zu sehen wie viele es werden.

    In den letzten Zwei Monaten waren das jetzt ca. 12 Stück die ich als “Blogwürdig” empfand. Ich denke, das reicht mir für die Kategorie.

    Aufbau

    Die Posts werden immer gleich aussehen und folgende Punkte enthalten:

    • Code
    • Hintergrund
    • Funktion
    • About “Shell-Zauberei”

    Informationen

    Kategorie URL: http://noqqe.de/archives/category/shell-zauberei


  14. Permalink
  15. statistical | It’s about internal functions.

    Als ich statistical auf GitHub hochgepushed habe, fing ich an mir Gedanken über die Leistungsfähigkeit des Scripts zu machen. Ich meine es verhielt sich in Anbetracht der Daten (in meinen Augen) wunderbar. Die Key Länge wird bis zu 4 Tab-Längen mit skaliert, genauso wie die Values, in Form der Bars. Aber wie verhält sich es mit größeren Datenmengen?

    Diesbezüglich wollte ich eine kleine For-Schleife benutzen um mehrere zufällige Werte zu generieren und in statistical zu pipen.

    time for x in $(seq 1 6000); do echo "$x:$RANDOM" ; done | statistical > /dev/null

    Das Ergebnis war mit 6000 Datensätzen und guten 7 Minuten relativ ernüchternd. Vor kurzem hat mich dann auch noch Vain via GitHub auf die Geschwindigkeit von statistical hingewiesen. In seinem Fork, hat er alle extern spawnenden Befehle gegen Bash interne Funktionen ausgetauscht. Siehe da:

    real 0m7.788s
    user 0m7.610s
    sys 0m0.250s

    Wahnsinn oder? Durch den Austausch von awk und grep durch interne Bash Funktionen wird das ganze ernsthaft 23x mal schneller. Vielen Dank an Vain an dieser Stelle!


  16. Permalink
  17. statistical | Statistiken visualisieren im Terminal

    Mir erschien es einen kurzen Moment lang für sinnvoll ein kleines Shell Tool zu haben, welches mir aus einer Liste von Key:Value Paaren eine Balkenstatistik baut und visualisiert. Wie in etwa $ statistical john:12 alice:5 linus:7 bob:1. Mir gefiel die Idee einfach alles mögliche in meinem Terminal ansehen zu können.

    Relativ schnell stieß ich aber an eine Grenze. Diese hieß “Windowsize”. Ich konnte nicht ohne bedenken eine Schleife die die Value Werte zählt bauen, die dementsprechend viele Zeichen anhängt. Denn bei Zahlen >10000 wird das ziemlich unlesbar :)

     while [ $COUNTER -lt $VALUE ]; do
            ((COUNTER++))
            echo -n "$OUTPUTCHAR"
            if [ $COUNTER -ge $VALUE ]; then
                echo
            fi
        done

    Ich brauchte ein Schema, welches alle Werte einließt und eine skalierbare Basis für alle Werte schafft. Ich entschied mich für eine simple Lösung.

    while [ ${FACTORCOUNT} -lt $(( ${#MAXVALUE} - 2 )) ]; do
    FACTOR="${FACTOR}0"
        ((FACTORCOUNT++))
    done
    

    Letztenendes kam dann folgendes Verhalten bei meinem Key:Value Statistik Script raus. Ich mags.

    # Beispiel
    $ statistical john:433 alice:49 linus:12 bob:231
    john    |###########################################
    alice   |####
    linus   |#
    bob     |#######################

    Damit lassen sich sogar teilweise sinnvolle Sachen produzieren. Zum Beispiel die Anzahl der Commits innerhalb eines Git-Repositories. Ich habe hier als Beispiel mal bash-it aufgeführt:

    for a in $(git shortlog -sn --all | cut -f2 | cut -f1 -d' '); do echo -n "$a:" ; git log $LOGOPTS --all --numstat --format="%n" --author=$a | cut -f3 | sort -iu | wc -l; done  | statistical
    Mark          |##################
    Robert        |#########################################################################
    Florian       |##############
    Jesus         |######
    John          |##############
    Rich          |########
    Piotr         |###
    Travis        |####
    Fedyashev     |##
    zerobearing2  |####
    Andy          |###
    Daniel        |####
    Jeff          |##
    Karl          |##
    Robert        |#########################################################################
    Sirupsen      |##
    

    Sollte jemand Interesse daran hegen, das Skript auch mal auszuprobieren es befindet sich wie immer auf Github: http://github.com/noqqe/statistical


  18. Permalink
  19. ZRE | SQL Statistik Modul

    Ich möchte kurz ein Wort über das SQL Modul verlieren, welches die Statistiken des permanent laufenden Zombie Environments aufzeichnet. Wie mit Sicherheit schon überall auf dem Planeten Erde bekannt ist, passieren in ZRE Events. Diese Hand voll Events lösen (wie der Name vielleicht schon suggeriert) Geschehnisse in innerhalb des Environments aus, welche es gilt statistisch auszuwerten und darzustellen.

    Han Solo & Chewbacca

    Wie aber erfasse ich solche Informationen am Besten. Ich hatte ehrlich gesagt keine große Lust, in jedes der Events einzeln eine SQL-Verbindung aufzubauen und den gewünschten Query abzusetzen. Ganz zu schweigen von der Problemfallbehandlung (MySQL nicht installiert, Modul in Config nicht aktiviert, MySQL nicht erreichbar usw.) die ich in jedem Event hätte extra behandeln müssen.

    events/
    ├── attack.humans.event
    ├── attack.zombies.event
    ├── born.humans.event
    ├── born.zombies.event
    ├── building.humans.event
    ├── collecting.zombies.event
    ├── die.humans.event
    ├── die.zombies.event
    ├── infos.event
    ├── stats.humans.event
    ├── stats.zombies.event
    ├── support.humans.event
    ├── support.zombies.event
    └── weather.event

    Stattdessen entschied ich mich ein kleines Modul in Bash zu schreiben, welches eine Hand voll übergebener Daten annimmt und dann in die konfigurierte Datenbank schreibt. Hier am Beispiel des weather.event

    case $nature_msg in
    1) echo "A volcano explodes." ; zresql weather vulcano ;;
    2) echo "An earthquake hits the city." ; zresql weather earthquake ;;
    3) echo "A hurricane hits the city." ; zresql weather hurricane ;;
    esac

    Als erstes übergeben wird immer der gewünschte Modus, in den zresql den Datensatz einordnen soll, danach alle weiteren Informationen die der Struktur nach erforderlich sind.

    # Hurricane
    $ zresql weather hurricane
    # Humans gewinnen einen Kampf und vernichten 643 Zombies
    $ zresql kill human 643

    Das zresql Modul nimmt die Informationen dann entgegen und leitet es unter den gegebenen Umständen via sqlsend an die Datenbank weiter.

    [...]
    weather) sqlsend "INSERT INTO zre_weather VALUES (NULL, \"$2\", CURRENT_TIMESTAMP);" ;;
    kill) sqlsend "INSERT INTO zre_kills VALUES (NULL , \"$2\", \"$3\", CURRENT_TIMESTAMP);" ;;
    [...]

    sqlsend ist im Grunde nur eine weitere kleine Funktion die direkt über Kommandozeile den SQL Query abschickt.

    sqlsend() {
    mysql -e "use $sqldb; $1" --user=$sqluser --password=$sqlpw --host=$sqlhost
    }

    Mit dieser Lösung bin ich eigentlich relativ zufrieden. Über Verbesserungsvorschläge und Kritik freue ich mich natürlich wie immer. Das ganze Modul ist zusehen auf Github: https://github.com/noqqe/zombie-revolution-environment/blob/master/lib/sqlstats.library.bash


Older »