Schleife wird zu schnell beendet

06/03/2008 - 11:18 von Michael Schmarck | Report spam
Hallo.

Gegeben ist folgendes Bash Scriptchen:

/usr/sbin/zfs list -H -t snapshot -o name | grep @backup | \
/bin/tail -r | while read name; do
if zfs destroy $name; then
echo "Destroyed ZFS Snapshot $name"
$logger -p$logger_prio -t"$lt" "Destroyed ZFS Snapshot $name"
else
echo "ZFS Snapshot $name could not be destroyed!"
$logger -p$logger_prio -t"$lt" "ZFS Snapshot $name could not be destroyed!"
fi
done

Nun stelle ich gerade fest, das die while Schleife nur 1× durchlaufen
wird, obwohl:

$ /usr/sbin/zfs list -H -t snapshot -o name | grep @backup | /bin/tail -r | wc -l
51

Es gibt also 51 Elemente und ich würde erwarten, das es auch 51
Durchlàufe gibt.

Gibt's aber nicht :(

$ sudo bash -x /.backup/populate destroy
+ . /.backup/configuration
++ swap_dev='n/a for winds06'
++ ufs_fs=(/ /var /u04)
++ backup_oracle=Yes
++ export_dir=/opt/apps/oracle/backup
++ fullbackup_date 071024
++ incrbackup_date 070925
++ policy=Unix_FS-Snapshots
+ logger_tag=backup
+ logger_prio=local5.debug
+ logger=/usr/bin/logger
+ backup_dir=/.backup
+ case $1 in
+ destroy
+ '[' -x /usr/sbin/zfs ']'
+ /usr/sbin/zfs list -H -t snapshot -o name
+ grep @backup
+ /bin/tail -r
+ read name
+ echo name=pool/netbackup-catalog/drf@backup
name=pool/netbackup-catalog/drf@backup
+ zfs destroy pool/netbackup-catalog/drf@backup
+ '[' 0 = 0 ']'
+ echo 'Destroyed ZFS Snapshot pool/netbackup-catalog/drf@backup'
Destroyed ZFS Snapshot pool/netbackup-catalog/drf@backup
+ /usr/bin/logger -plocal5.debug -t 'Destroyed ZFS Snapshot pool/netbackup-catalog/drf@backup'
+ read name
+ exit 0

Das ganze wird auf einem Solaris 10 System mit

$ /bin/bash --version
GNU bash, version 3.00.16(1)-release (sparc-sun-solaris2.10)
Copyright (C) 2004 Free Software Foundation, Inc.

ausgeführt.

Warum bricht die Schleife nach dem ersten Durchlauf ab?

Michael
 

Lesen sie die antworten

#1 Heike C. Zimmerer
06/03/2008 - 12:35 | Warnen spam
Michael Schmarck writes:

Hallo.

Gegeben ist folgendes Bash Scriptchen:

/usr/sbin/zfs list -H -t snapshot -o name | grep @backup | \
/bin/tail -r | while read name; do
if zfs destroy $name; then
echo "Destroyed ZFS Snapshot $name"
$logger -p$logger_prio -t"$lt" "Destroyed ZFS Snapshot $name"
else
echo "ZFS Snapshot $name could not be destroyed!"
$logger -p$logger_prio -t"$lt" "ZFS Snapshot $name could not be destroyed!"
fi
done

Nun stelle ich gerade fest, das die while Schleife nur 1× durchlaufen
wird, obwohl:

$ /usr/sbin/zfs list -H -t snapshot -o name | grep @backup | /bin/tail -r | wc -l
51

Es gibt also 51 Elemente und ich würde erwarten, das es auch 51
Durchlàufe gibt.



Ich kann nichts Ungewöhnliches entdecken. Mir fàllt auf, dass es
besser 'IFS= read -r' heißen sollte, solange nicht sicher bekannt ist,
dass der Input bestimmte Beschrànkungen einhàlt. Das dürfte aber mit
Deinem Problem nichts zu tun haben.

Ein paar Ideen:

Nach Deinem Output:
+ read name
+ exit 0


bricht der read ab. Vielleicht gibt der Exit-Status etwas mehr
Auskunft (Du müsstest nachschauen, ob es beim Exit-Status von read in
der Bash aussagekràftige Unterschiede gibt und Dir den ausgeben).

Der read in Bash kennt eine Timeout-Umgebungsvariable (IIRC
$TIMEOUT). Ist die gesetzt, bricht der nach der gesetzten Zeit ab.
Man kann ein -t 0 anfügen (eine unportable Option zum Abschalten eines
unportablen 'Features').

Was passiert, wenn Du wc -l durch (while IFS= read -r name; printf
"#%s#" "$name") ersetzt? Dann dürfte auch nur eine Zeile kommen.

Was steht in der zweiten Zeile, wenn Du die while-Schleife durch eine
Dateiumleitung ersetzt?

Ähnliche fragen