Adalbert Dawid <dawid@rinux.net> (So 26 Aug 2007 19:03:43 CEST):
> Hallo Liste!
>
> Preisfrage: was stimmt nicht am folgenden Konstrukt?
>
> #!/bin/bash
> find /bin | while read FILE; do
> echo "Datei ${FILE} existiert."
> read -p "Löschen? (y/n)" -n 1 REPLY
> if [ ${REPLY} = "y" ]; then rm -f ${FILE}; fi
> done
>
> Das Skript ist zwar sinnlos, aber es soll nur mein Problem verdeutlichen:
> Das read innerhalb der Schleife "funktioniert nicht". Hat jemand eine
> Erklärung? Dieses kleine aber überaus nervige Problem taucht übrigens auch
> in der folgenden Minimalkonfiguration auf:
>
> find /bin | while read FILE; do read REPLY; done
>
> Auch hier wird REPLY nie von read abgefragt!
> Das Konstrukt
... Beide "read" lesen von der Standard-Eingabe, und die wird ja von
"find" gefüttert.
Vielleicht kann man dem inneren Read beibringen, z.B. von /dev/tty zu
lesen...
> for FILE in `find /bin`; do read REPLY; done
>
> würde zwar prinzipiell gehen, ich brauche aber die Variante mit while,
> weil nur diese imstande ist Dateinamen mit Leerzeichen im Namen korrekt zu
> verarbeiten. Das for zerlegt jeden Dateinamem mit Leerzeichen in mehrere
> Tokens, das while trennt immer nur an Zeilenumbrüchen.
Das mag *ein* Grund sein, der ernsthaftere Grund wäre, daß dieses
for FILE in `find /bin`; ....
eventuell eine sehr lange Liste von Filenamen erzeugt, die für die Shell
dort, wo die `...` stehen, dann zu lang ist. (Wobei die Bash es zu
vertragen scheint, da "for" ein Builtin ist).
In *beiden* Fällen (for / while) hast Du Probleme, wenn Zeilenumbrüche
im Filenamen sind. Und auch das soll passieren :)
find /bin -print0 | while read -0 FILE; do
echo "$FILE"
done
Nur, das gibt's leider nicht in der Bash. In anderen Shells weiß ich es
nicht. Also mußt Du vielleicht was basteln mit "xargs -0".
--
Heiko
Attachment:
signature.asc
Description: Digital signature