Dank der Semesterferien fand ich nun endlich Zeit, mein aerotools-Projekt auf Vordermann zu bringen. Neben einigen Bugfixes und Vereinfachungen am Daemon habe ich die Library auf libusb-1.0 portiert, was laut Homepage die empfohlene, aktuelle Version ist. Unter Arch coexistiert sie als libusb1 neben der libusb, die standardmäßig installiert wird – etwas verwirrend, wenn man den Hinweistext auf der Homepage nicht gelesen hat
Alle aquaero®-Besitzer seien also herzlich eingeladen, die neue Version zu testen! Bugreports sind immer willkommen, am Besten über die “Issues”-Funktion auf Github.
Beim Ändern von ignore-Regelsätzen für logcheck unterlaufen mir ganz gern Tippfehler in komplexeren Ausdrücken. Dumm nur, wenn ich das erst beim nächsten Cron-Run merke, in Form einer solchen Meldung:
egrep: Unmatched ) or \)
Toll: weder Regelsatz noch Zeilennummer werden genannt, also manuell suchen. Da es sich aber meist um umfangreiche Regelsätze handelt und ich (selbst bei gefundenem Satz) keine Möglichkeit gefunden habe, egrep die Zeilennummer des ungültigen Ausdrucks zu entlocken, entstand auf die Schnelle folgendes simples Script:
#!/bin/bash
if [ $# -ne 1 ]; then
echo "usage: $0 RULES_FILE"
exit 1
fi
if ! [ -r "$1" ]; then
echo "unable to read $1"
exit 1
fi
LINES=$(wc -l "$1" | cut -d ' ' -f 1)
for I in $(seq $LINES); do
echo "line $I..."
echo "foo" | egrep "$(cat "$1" | head -n $I | tail -n 1)"
done
exit 0
Es gibt bestimmt auch irgendeine elegantere Lösung, aber vielleicht erspart es ja jemandem die nervige Sucherei
Dieser animierte Blogpost beschreibt meinen Abend perfekt

In meinem Arch Ramdisk-Script <1.4 hatte sich ein dämlicher Bug eingeschlichen: bei sämtlichen rsync-Aufrufen fehlte das --delete.
Das bewirkt z.B. bei Verwendung mit Firefox, dass der Cache nie geleert wird und (streng) monoton wächst – unschön.
Hier die gefixte Version
#!/bin/sh
#
# Manages outsourcing of specified directories into memory on bootup and
# takes care of synchronization/backup on system shutdown.
#
# Version 1.4, 2010-04-26, by Alexander Koch
#
# includes
. /etc/rc.conf
. /etc/rc.d/functions
# configuration (syntax is: [persist. storage]:[mountpoint]:[mount options])
DISKS=('/home/alex/.ramdisks/_mozilla:/home/alex/.mozilla:size=100M,uid=1000,gid=100' \
'empty:/home/alex/.adobe:size=10M,uid=1000,gid=100' \
'empty:/home/alex/.macromedia:size=10M,uid=1000,gid=100')
# helper functions
function activate_rd() {
[ -d "$1" ] || [ "$1" = "empty" ] || return 1
[ -d "$2" ] || return 1
mount | grep "$2" &>/dev/null && return 1
MNT="mount -t tmpfs"
[ -z "$3" ] || MNT="$MNT -o $3"
$MNT none "$2"
[ $? -gt 0 ] && return 1
if [ "$1" != "empty" ]; then
for D in $1/.* $1/*; do
[ "$(basename "$D")" == "." ] && continue
[ "$(basename "$D")" == ".." ] && continue
rsync -axq "$D" "$2" &>/dev/null
if [ $? -gt 0 ]; then
umount "$2"
return 1
fi
done
fi
return 0
}
function backup_rd() {
mount | grep "$1" &>/dev/null || return 0
if [ "$2" != "empty" ]; then
for D in $1/.* $1/*; do
[ "$(basename "$D")" == "." ] && continue
[ "$(basename "$D")" == ".." ] && continue
rsync -axq --delete "$D" "$2" &>/dev/null
if [ $? -gt 0 ]; then
tar -cf "/root/$(basename "$2")-failed.tar" "$1"
return 1
fi
done
fi
umount "$1" || return 1
return 0
}
# main logic
case $1 in
start)
stat_busy "Mounting ramdisks"
error=0
for M in ${DISKS[@]}; do
FROM="$(echo "$M" | cut -d ':' -f 1)"
TO="$(echo "$M" | cut -d ':' -f 2)"
OPTS="$(echo "$M" | cut -d ':' -f 3)"
activate_rd "$FROM" "$TO" "$OPTS" || error=1
done
if [ $error -eq 0 ]; then
add_daemon ramdisks
stat_done
else
stat_fail
exit 1
fi
;;
stop)
stat_busy "Saving ramdisks"
error=0
for M in ${DISKS[@]}; do
FROM="$(echo "$M" | cut -d ':' -f 2)"
TO="$(echo "$M" | cut -d ':' -f 1)"
backup_rd "$FROM" "$TO" || error=1
done
if [ $error -eq 0 ]; then
rm_daemon ramdisks
stat_done
else
stat_fail
echo -n "WARNING: failed to save ramdisk(s), tried to make "
echo "backup(s) under /root."
echo "Hit enter to proceed shutdown."
read DUMMY
exit 1
fi
;;
restart)
if ! ck_daemon ramdisks; then
"$0" stop && sleep 3
fi
"$0" start
;;
*)
echo "usage: $0 {start|stop|restart}"
;;
esac
exit 0
Mein Arch ramdisk-script hat ein weiteres Update erfahren, die Konfiguration ist nun mehr nach KISS und dot-Ordner werden korrekt behandelt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
| #!/bin/sh
#
# Manages outsourcing of specified directories into memory on bootup and
# takes care of synchronization/backup on system shutdown.
#
# Version 1.3, 2010-03-15, by Alexander Koch
#
# includes
. /etc/rc.conf
. /etc/rc.d/functions
# configuration (syntax is: [persist. storage]:[mountpoint]:[mount options])
DISKS=('/home/alex/.ramdisks/_mozilla:/home/alex/.mozilla:size=100M,uid=1000,gid=100' \
'empty:/home/alex/.adobe:size=10M,uid=1000,gid=100' \
'empty:/home/alex/.macromedia:size=10M,uid=1000,gid=100')
# helper functions
function activate_rd() {
[ -d "$1" ] || [ "$1" = "empty" ] || return 1
[ -d "$2" ] || return 1
mount | grep "$2" &>/dev/null && return 1
MNT="mount -t tmpfs"
[ -z "$3" ] || MNT="$MNT -o $3"
$MNT none "$2"
[ $? -gt 0 ] && return 1
if [ "$1" != "empty" ]; then
for D in $1/.* $1/*; do
[ "$(basename "$D")" == "." ] && continue
[ "$(basename "$D")" == ".." ] && continue
rsync -axq "$D" "$2" &>/dev/null
if [ $? -gt 0 ]; then
umount "$2"
return 1
fi
done
fi
return 0
}
function backup_rd() {
mount | grep "$1" &>/dev/null || return 0
if [ "$2" != "empty" ]; then
for D in $1/.* $1/*; do
[ "$(basename "$D")" == "." ] && continue
[ "$(basename "$D")" == ".." ] && continue
rsync -axq "$D" "$2" &>/dev/null
if [ $? -gt 0 ]; then
tar -cf "/root/$(basename "$2")-failed.tar" "$1"
return 1
fi
done
fi
umount "$1" || return 1
return 0
}
# main logic
case $1 in
start)
stat_busy "Mounting ramdisks"
error=0
for M in ${DISKS[@]}; do
FROM="$(echo "$M" | cut -d ':' -f 1)"
TO="$(echo "$M" | cut -d ':' -f 2)"
OPTS="$(echo "$M" | cut -d ':' -f 3)"
activate_rd "$FROM" "$TO" "$OPTS" || error=1
done
if [ $error -eq 0 ]; then
add_daemon ramdisks
stat_done
else
stat_fail
exit 1
fi
;;
stop)
stat_busy "Saving ramdisks"
error=0
for M in ${DISKS[@]}; do
FROM="$(echo "$M" | cut -d ':' -f 2)"
TO="$(echo "$M" | cut -d ':' -f 1)"
backup_rd "$FROM" "$TO" || error=1
done
if [ $error -eq 0 ]; then
rm_daemon ramdisks
stat_done
else
stat_fail
echo -n "WARNING: failed to save ramdisk(s), tried to make "
echo "backup(s) under /root."
echo "Hit enter to proceed shutdown."
read DUMMY
exit 1
fi
;;
restart)
if ! ck_daemon ramdisks; then
"$0" stop && sleep 3
fi
"$0" start
;;
*)
echo "usage: $0 {start|stop|restart}"
;;
esac
exit 0 |
Mein bereits erwähntes lighttpd-vhost-script hat ein Update erfahren und unterstützt jetzt Subdomains und Vhost- sowie Subdomain-spezifische configs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| #!/bin/bash
VHOST_ROOT="/var/www"
VHOST_DEF="default"
VHOST_CONF="vhost.conf"
SBD_ROOT="subdomains"
DOC_ROOT="htdocs"
for VHOST in $(find $VHOST_ROOT -mindepth 1 -maxdepth 1 -type d -exec basename {} \;); do
# skip default vhost
if [ "$VHOST_DEF" == "$VHOST" ]; then
continue
fi
echo "\$HTTP[\"host\"] =~ \"^(www\.|)$VHOST\" {"
echo " server.document-root = \"$VHOST_ROOT/$VHOST/$DOC_ROOT\""
echo " accesslog.filename = \"/var/log/lighttpd/$VHOST.access.log\""
if [ -e "$VHOST_ROOT/$VHOST/$VHOST_CONF" ]; then
# include vhost config
cat "$VHOST_ROOT/$VHOST/$VHOST_CONF"
fi
echo "}"
echo ""
# subdomains
if [ -d "$VHOST_ROOT/$VHOST/$SBD_ROOT" ]; then
for SBD in $(find $VHOST_ROOT/$VHOST/$SBD_ROOT -mindepth 1 -maxdepth 1 -type d -exec basename {} \;); do
echo "\$HTTP[\"host\"] =~ \"^$SBD.$VHOST\" {"
echo " server.document-root = \"$VHOST_ROOT/$VHOST/$SBD_ROOT/$SBD/$DOC_ROOT\""
echo " accesslog.filename = \"/var/log/lighttpd/$VHOST.access.log\""
if [ -e "$VHOST_ROOT/$VHOST/$SBD_ROOT/$SBD/$VHOST_CONF" ]; then
# include subdomain's custom config
cat "$VHOST_ROOT/$VHOST/$SBD_ROOT/$SBD/$VHOST_CONF"
fi
echo "}"
done
echo ""
fi
done |
Aus meiner Gentoo-Zeit habe ich oft etc-update vermisst, was sich um das Aktualisieren von Configs kümmert. Als Arch-Pendant hier mal mein Ansatz in Form eines Bash-Scripts. Es findet aktualisierende und verwaiste .pacnew, sowie überholte .pacsave und arbeitet sie interaktiv sequentiell ab.
#!/bin/sh
DIR="/etc"
if [ $(id -u) -gt 0 ]; then
sudo $0
exit $?
fi
function work()
{
ANS="z"
while echo "$ANS" | egrep -v '^[0-3]$' &>/dev/null; do
echo "$1:"
echo " [0] colordiff (old->new)"
echo " [1] upgrade (overwrite)"
echo " [2] keep (delete .pacnew)"
echo " [3] skip"
echo -n "choice: "
read ANS
done
case $ANS in
0)
colordiff "$1" "$2"
work "$1" "$2"
;;
1)
mv "$2" "$1" || exit 1
;;
2)
rm "$2" || exit 1
;;
3)
true
;;
*)
work "$1" "$2"
;;
esac
}
PACNEW="$(find $DIR -iname '*.pacnew' 2>/dev/null)"
PACSAV="$(find $DIR -iname '*.pacsave' 2>/dev/null)"
for FILE in $PACNEW; do
CONF="${FILE%.pacnew}"
if [ -e "$CONF" ]; then
work "$CONF" "$FILE"
else
echo -n "$FILE orphaned, delete? [Y/n] "
read ANS
if [ "$ANS" == "Y" -o "$ANS" == "y" -o "$ANS" == "" ]; then
rm "$FILE" || exit 1
fi
fi
done
for FILE in $PACSAV; do
CONF="${FILE%.pacsave}"
if [ -e "$CONF" ]; then
echo -n "$CONF obsolete ($(basename $CONF) present), delete? [Y/n] "
else
echo -n "$FILE remaining, delete? [Y/n] "
fi
read ANS
if [ "$ANS" == "Y" -o "$ANS" == "y" -o "$ANS" == "" ]; then
rm "$FILE" || exit 1
fi
done
exit 0
Wie immer der Hinweis: Benutztung auf eigene Gefahr!
Update: Ja, ich kenne yaourt und weiß um yaourt -C Bescheid *grml*, aber warum yaourt benutzen, wenn man auch ein Bashscript schreiben kann?
Eine Sache, die mich seit einigen Monaten immer wieder ganze Abende gekostet hat und über die ich schon lange bloggen wollte, aber nie Zeit fand: Verbose cp, aka vcp.
vcp soll das Gleiche tun wie cp, allerdings mit Fortschrittsanzeige und ETA. Geboren wurde die Idee dafür, als ich einen Aufhänger gesucht habe, endlich mal richtig C zu lernen, und mich daran erinnerte, wie sehr ich die gepatchten coreutils aus Gentoo-Zeiten vermisse, wenn ich in einer ssh-Session mal wieder am Verschieben einer größeren Datei bin und mich frage, wann das dämliche Ding endlich fertig ist.
Ich habe versucht, den Code so simpel wie möglich zu halten, um KISS treu zu bleiben. Gelungen ist mir das sicher nicht überall, aber da es ja ein Lernprojekt ist und ich noch keinen umfassenden Überblick über die Standardbibliotheken habe, sehe ich das nicht als tragisch an.
Im Moment befindet sich das Tool in einer schon recht brauchbaren Phase: reguläre Dateien und Ordner (yey, Rekursion!
) können bereits kopiert werden, die Fortschrittsanzeige ist ebenfalls implementiert und liefert Datei- und Jobstatus, sowie ETA und gemittelte Geschwindigkeit. Ebenfalls praktisch: fehlgeschlagene Dateien werden übergangen und erst am Ende bemängelt, d.h. man muss nicht bei jedem Fehler immer von vorne beginnen, sondern kann sich beim zweiten Versuch auf die Problemfälle konzentrieren und bereits vorhandene Dateien automatisch überspringen lassen.
Um nicht in detaillierte Beschreibungen der Funktionalität abzudriften sei an dieser Stelle genug der Vorstellung, wer bereits einen Blich auf meine Arbeit werfen möchte, kann den Code (steht unter GPLv3) über http://github.com/lynix/vcp beziehen und ausprobieren. Es sei noch darauf hingewiesen, dass sich das Tool in der Entwicklung befindet, Benutzung auf eigene Gefahr!
Sobald ich mehr Zeit habe, bekommt das Ding dann auch noch eine rudimentäre Homepage mit besserer Dokumentation.
Wer über Nacht große Downloads auf der Xorg-losen Box laufen lassen will, braucht einen wget-tauglichen Link. Oft wird gerade dieser jedoch von der anbietenden Seite auf Biegen und Brechen zu verschleiern versucht. Es gibt zwar für jede Taktik auch eine geeignete Gegenmaßnahme (sonst würde der Download per Browser ja auch nicht funktionieren), wer sich aber das Suchen und Basteln sparen möchte und auch gern mal viele Links ohne großen Aufwand zusammenklicken will, kann folgende Methode nutzen:
Über das Firefox-Addon FlashGot lässt sich ein benutzerdefinierter Downloadmanager einrichten, an den FlashGot dann die URL und wahlweise diverse andere Informationen wie Header, etc. weiter gibt.
Als so ein Downloadmanager dient beispielsweise folgendes kleines Bash-script, welches alle ihm übergebenen Links eines bekannten 1-Click-Hosters (
) unter ~/links.txt ablegt:
#!/bin/sh
echo "$1" | sed -e 's/\/.*\.rapid/\/\/rapid/' >> ~/links.txt
exit 0
Wieder ein ziemlicher dirty-hack, der mir einen Dorn aus dem Auge zieht – diesmal an xfce4-notifyd, dem lightweight-Ersatz für notification-daemon.
Gestört hatte mich die Formatierung der Popup-Überschriften (summaries), die sich nicht von der des Textes unterscheidet, weshalb man Text und Überschrift auf den ersten Blick kaum trennen konnte. Ein Eingriff in die Sourcen macht die Überschriften bei mir jetzt fett, hier der Patch (für die xfce-notify-window.c aus xfce4-notifyd-0.1.0).
Wenn jemand eine Lösung über die gtkrc der Themes findet, möge er mich doch bitte erleuchten