Hallo, danke für den Kommentar auf mein Skript! Hätte ich gar nicht erwartet ... Ich möchte vorab nur bemerken, daß _mein_ Skript ganz ausgezeichnet funktioniert. Deshalb nehme ich Deinen Kommentar mal einfach als Beitrag zur ästhetischen Verbesserung, d.h. um das Skript eleganter (= meistens einfacher) zu machen, und das kann ja durchaus ebenso lehrreich sein. Ich bin schon ganz gespannt, wie meine persönlichen Fortschritte im bash-scripting sind, denn eigentlich wollte ich es vermeiden und stattdessen lieber Python verwenden. Aber ich sehe schon jetzt, daß zumindest für kleine Angelegenheiten - wenn keine komplexen Abläufe oder umfangreiche Textverarbeitung gefragt sind - bash-Skripte fast unausweichlich sind. Jan Trippler schrieb:
Thomas, Deine Zeilen sind zu lang - die Lesbarkeit leidet deutlich!
Ja, das war mir klar, als ich vorübergehend den automatischen Zeilenumbruch auf 100 Zeichen erhöht habe. Der Grund war, daß sonst mein Skript fast unlesbar geworden wäre. Leider war ich auch zu faul, um manuell <Enter> zu drücken nach ungefähr 70 - 80 Zeichen. Das werde ich jetzt beherzigen. Aber bei Skripten habe ich, ehrlich gesagt, nichts gegen eine Zeilenlänge bis 100 Zeichen. In normalem Text habe ich auch 70 - 80 Zeichen *viel* lieber.
On Son, 27 Apr 2003 at 21:48 (+0200), Thomas Michalka wrote:
Manfred Tremmel schrieb:
Sorry, 2. Versuch, die erste Mail war noch nicht fertig ...
Am Samstag, 26. April 2003 13:59 schrieb Thomas Michalka:
[...] Also wenn die Werte zusammengehören und Du die auch in eine Variable legen kannst, tuts vielleicht ein:
VAR="A|0|Z B|1|Y C|2|X D|3|W E|4|V F|5|U"
for param in $VAR ; do parm_v=`echo $param | awk -F \| '{print $1}'` parm_n=`echo $param | awk -F \| '{print $2}'` parm_t=`echo $param | awk -F \| '{print $3}'` echo $param_v $param_n $param_t done
Ich würde dafür nur keinen awk nehmen, ein einfacher cut -f1 -d\|
Ganz gut, das habe ich anläßlich eines anderen Skripts erst danach herausgefunden.
tuts auch. awk ist dafür deutlich oversized und auch etwas ressourcenfressender. jan@k500:~/tmp> ls -l /bin/gawk /usr/bin/cut -rwxr-xr-x 1 root root 209420 Mär 25 2002 /bin/gawk -rwxr-xr-x 1 root root 18968 Mär 23 2002 /usr/bin/cut
Aber sei mal ehrlich, sollte mich das bei 1 GB Hauptspeicher wirklich jucken?
awk '{print $'$position'}' # hier darf außer zw. 'print' und '$' KEIN Leerraum enthalten sein!!!
Unsinn, wo hast Du das denn her? jan@k500:~/tmp> pos=2 jan@k500:~/tmp> echo "1 2 3" | awk ' { print $'$pos' } ' 2
Lediglich das Konstrukt $'$pos' muss zusammen geschrieben werden.
So ist es! Eigentlich wollte ich mich nur auf das Statement innnerhalb der Klammer beziehen, aber ich habe das nicht korrekt ausgedrückt.
BTW: jan@k500:~/tmp> echo "1 2 3" | cut -f$pos -d" " 2
funktioniert genauso gut.
Auch sehr schön!
[...]
# The mount point directory MP_DIR=/mnt
# ------------------------------------------------------------------------ POS_NUM=" 1 2 3 4 5 6 7 8 9" # ------------------------------------------------------------------------ DEV_NUM=" 2 5 6 7 8 9 10 11 12" MPT_LST=" 02 05 06 07 08 09 10 11 12" SRC_LST=" /boot / /root /tmp /opt /usr /usr/local /var /home" NME_LST=" BOOT_FS ROOT_FS ADMIN_FS TMP_FS OPT_FS USR_FS USRLOCAL_FS VAR_FS HOME_FS"
# Let's sync the filesystems now! for position in $POS_NUM ; do
devnum=$(echo -n $DEV_NUM | awk '{print $'$position'}') mpoint=$(echo -n $MPT_LST | awk '{print $'$position'}') source=$(echo -n $SRC_LST | awk '{print $'$position'}') fsname=$(echo -n $NME_LST | awk '{print $'$position'}')
Finde ich ziemlich umständlich, jetzt wo ich sehe, was Du damit machen willst. Wie wäre es so:
echo "2 02 /boot BOOT_FS 5 05 / ROOT_FS 6 06 /tmp TMP_FS" |\ while read devnum mpoint source fsname; do ... done
Man könnte auch eine Konfigurationsdatei aufbauen, die den gleichen Aufbau wie der echo haben kann, und dann geht es einfach mit:
cat datei | while read devnum mpoint source fsname; do ...
Schaut auch recht schön aus. Für mich war es nur alles andere als selbstverständlich, daß read einmal von stdin und von einer Zeichenkette so liest, daß nach jedem Whitespace quasi neu begonnen wird mit dem Lesevorgang. Ich habe mir 'man bash' natürlich auch angesehen, aber das Ding ist ja sooo lang, und nicht gerade didaktisch gegliedert (was wohl auch nicht beabsichtigt war), und da wußte ich als Bash-Unerfahrener noch nichts von 'read'. Überhaupt hält die bash wohl noch viel überraschendes für mich bereit ...
# Is the file system already mounted? if [ 0 -eq $(mount | grep -c "\/dev\/hdb$devnum") ] ; then
David würden sich jetzt wieder die Fußnägel aufrollen ;-)
Wen meinst Du? Ich habe von keinem David in diesem Thread gelesen, oder ist das so ein Insider-Witz?
if ! mount | grep -q /dev/hdb$devnum; then
Du meine Güte, es geht wohl immer noch irgendwie einfacher? Aber ich habe nun mal nicht die Zeit, immer noch etwas päpstlicher als der Papst zu sein ;-)
mount /dev/hdb$devnum $MP_DIR/$mpoint & PID_MOUNT=$! wait $PID_MOUNT 2> /dev/null
Was hat das für einen Sinn? Du schickst den Prozess in den Hintergrund und anschließend wartest Du doch auf ihn. Warum dann nicht gleich mount /dev/hdb$devnum $MP_DIR/$mpoint
Habe ich zuerst auch versucht, aber aus mir unerfindlichen Gründen bekam ich eine Meldung, wonach das Device schon gemountet sei, obwohl das *definitiv* nicht der Fall war. Das konnte ich reproduzieren, aber mir ist bis heute schleierhaft, was die Ursache ist. Leider habe ich gerade nicht genug Zeit, dem auf den Grund zu gehen.
und ich würde den Status abfragen! if ! mount /dev/hdb$devnum $MP_DIR/$mpoint; then echo Fehler beim mount exit 1 fi
Ist natürlich viel sauberer. Aber wenn das Gerät schon gemountet ist, ergibt 'echo $?' -> 32. In dem Fall soll das Skript weitermachen. Deshalb ist Deine Lösung hier auch etwas zu einfach. (Keine Angst, damit komme ich klar :-) )
rsync $RSYNC_OPTS $source/ $MP_DIR/$mpoint/ & PID_RSYNC=$! wait $PID_RSYNC 2> /dev/null ; echo "done (process $PID_RSYNC)."
Auch hier wieder: Was hat es für einen Sinn, das Kommando in den Hintergrund zu schicken, wenn Du doch auf die Beendigung wartest?
Das hier hat den historischen Grund, daß nach dem Start von rsync noch andere Jobs parallel laufen sollten, aber sichergestellt werden mußte, daß der nächste rsync-Job _nach_ dem vorherigen gestartet würde. Die Teile zwischen PID_RSYNC=$! und dem wait-Kommando wurden gelöscht, aber der Rest sollte erhalten bleiben, falls es sich wieder einmal anders ergeben würde. Danke nochmals für die nützlichen Hinweise. Kannst Du mir vielleicht ein Buch über die Bash empfehlen? Ich habe da eher an ein Nachschlagewerk gedacht, als an ein klassisches Lehrbuch, was man von vorne bis hinten durcharbeiten muß. Ich brauche eigentlich auch keine Hinweise über das Programmieren als solches, eher schon weitergehende Tips über effizientes Scripting mit der bash. Und das wichtigste: Einen guten und ausführlichen Index sollte es haben. Gruß, Thomas