Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

find Dateiname {} mehrfach verwenden

2 views
Skip to first unread message

Marco Moock

unread,
Jun 20, 2023, 6:16:19 AM6/20/23
to
Hallo zusammen!

Ich schaffe es nicht, mehrfach den gefundenen Dateinamen zu verwenden.

find -name "xx*" -exec head -n 1 {} > {}-create \;
resultiert in einer einzigen Datei namens {}-create.

Wie kann ich erreichen, dass die find-Funktion {} mehrfach genutzt
werden kann?
Variablen einbauen will ich eigentlich nicht.

--
Gruß
Marco

Ulli Horlacher

unread,
Jun 20, 2023, 7:38:40 AM6/20/23
to
Stefan Ram <r...@zedat.fu-berlin.de> wrote:
> Marco Moock <mo...@posteo.de> writes:
>>Wie kann ich erreichen, dass die find-Funktion {} mehrfach genutzt
>>werden kann?
>
> Hier führt
>
> find . -exec echo {} {} \;
>
> beispielsweise durchaus zur einer Ausgabe, in welcher der gefundene
> Pfad zwiefach in einer Zeile steht.
>
> find . -exec echo "ok" > {}.txt \;
>
> legt hingegen hier ".txt" an

Klar, weil {} von find expandiert wird, wenn du es als Argument uebergibst.
Alles nach ">" sieht find aber nicht und kann es daher auch nicht
expandieren.


> find . -exec echo "ok" > \{\}.txt \;
>
> "{}.txt". (Ich verwendet möglicherweise eine C-shell.)

MOEGLICHERWEISE?!
Du weisst nicht mal, welche Shell du verwendest?!
OHJE.


> Das Problem könnte sein, daß die Umleitung hinter "-exec" gar nicht
> möglich ist. Was jedoch gehen könnte, wäre etwas wie:
>
> find . -exec bash -c 'echo "$1" > "$1.txt"' sh {} \;

Ganz kalt. Falsche Vermutung, falsche Schlussfolgerung.



--
Ullrich Horlacher Server und Virtualisierung
Rechenzentrum TIK
Universitaet Stuttgart E-Mail: horl...@tik.uni-stuttgart.de
Allmandring 30a Tel: ++49-711-68565868
70569 Stuttgart (Germany) WWW: https://www.tik.uni-stuttgart.de/

Marco Moock

unread,
Jun 20, 2023, 7:47:09 AM6/20/23
to
Am 20.06.2023 um 11:38:39 Uhr schrieb Ulli Horlacher:

> Stefan Ram <r...@zedat.fu-berlin.de> wrote:
> > Marco Moock <mo...@posteo.de> writes:
> >>Wie kann ich erreichen, dass die find-Funktion {} mehrfach genutzt
> >>werden kann?
> >
> > Hier führt
> >
> > find . -exec echo {} {} \;
> >
> > beispielsweise durchaus zur einer Ausgabe, in welcher der
> > gefundene Pfad zwiefach in einer Zeile steht.
> >
> > find . -exec echo "ok" > {}.txt \;
> >
> > legt hingegen hier ".txt" an
>
> Klar, weil {} von find expandiert wird, wenn du es als Argument
> uebergibst. Alles nach ">" sieht find aber nicht und kann es daher
> auch nicht expandieren.

Warum sieht find das nicht?
Es ist doch Teil des Arguments von -exec, oder?

Ulli Horlacher

unread,
Jun 20, 2023, 7:51:23 AM6/20/23
to
Marco Moock <mo...@posteo.de> wrote:

> Ich schaffe es nicht, mehrfach den gefundenen Dateinamen zu verwenden.
>
> find -name "xx*" -exec head -n 1 {} > {}-create \;
> resultiert in einer einzigen Datei namens {}-create.
>
> Wie kann ich erreichen, dass die find-Funktion {} mehrfach genutzt
> werden kann?

find kann das, Beispiel:

framstag@diaspora:/tmp: find . -name "*.png" -exec echo eins: {} zwei: {} \;
eins: ./framstag/X-20230619113542.png zwei: ./framstag/X-20230619113542.png
eins: ./framstag/X-20230619113620.png zwei: ./framstag/X-20230619113620.png
eins: ./framstag/X-20230619113723.png zwei: ./framstag/X-20230619113723.png
eins: ./framstag/X-20230619122545.png zwei: ./framstag/X-20230619122545.png
eins: ./phoon.png zwei: ./phoon.png
eins: ./xplanet.png zwei: ./xplanet.png


Alles nach ">" (oder "<" "|" "&&" "||") sieht find aber nicht und kann es
daher nicht interpretieren (expandieren).

Das was du aber vor hast, geht mit find nicht (alleine). Du musst deshalb
entweder ein Skript aussen rum bauen oder zB with(*) verwenden:

framstag@moep:/tmp: with *png : "echo %f > %f.txt"

framstag@diaspora:/tmp: ll *png*
-rw-r--r-- framstag users 28,030 2023-06-19 11:27:20 phoon.png
-rw-r--r-- framstag users 10 2023-06-20 13:47:54 phoon.png.txt
-rw-r--r-- framstag users 950,268 2023-06-20 13:47:21 xplanet.png
-rw-r--r-- framstag users 12 2023-06-20 13:47:54 xplanet.png.txt


(*) https://fex.belwue.de/fstools/with.html

Ulli Horlacher

unread,
Jun 20, 2023, 7:53:34 AM6/20/23
to
Weil die Shell das gar nicht an find uebergibt.


> Es ist doch Teil des Arguments von -exec, oder?

Oder! Nein.
Dein find-Kommando endet vor dem ">"

Marco Moock

unread,
Jun 20, 2023, 8:08:34 AM6/20/23
to
Am 20.06.2023 um 11:53:32 Uhr schrieb Ulli Horlacher:

> Marco Moock <mo...@posteo.de> wrote:
> > Am 20.06.2023 um 11:38:39 Uhr schrieb Ulli Horlacher:
> >
> >> Stefan Ram <r...@zedat.fu-berlin.de> wrote:
> >> > Marco Moock <mo...@posteo.de> writes:
> >> >>Wie kann ich erreichen, dass die find-Funktion {} mehrfach
> >> >>genutzt werden kann?
> >> >
> >> > Hier führt
> >> >
> >> > find . -exec echo {} {} \;
> >> >
> >> > beispielsweise durchaus zur einer Ausgabe, in welcher der
> >> > gefundene Pfad zwiefach in einer Zeile steht.
> >> >
> >> > find . -exec echo "ok" > {}.txt \;
> >> >
> >> > legt hingegen hier ".txt" an
> >>
> >> Klar, weil {} von find expandiert wird, wenn du es als Argument
> >> uebergibst. Alles nach ">" sieht find aber nicht und kann es daher
> >> auch nicht expandieren.
> >
> > Warum sieht find das nicht?
>
> Weil die Shell das gar nicht an find uebergibt.
>
>
> > Es ist doch Teil des Arguments von -exec, oder?
>
> Oder! Nein.
> Dein find-Kommando endet vor dem ">"

Wie kommst das zustande?
Baut find nicht aus den gefundenen Dateien passende Kommandos?
Wie wird das sonst technisch umgesetzt?

Ulli Horlacher

unread,
Jun 20, 2023, 8:22:53 AM6/20/23
to

Marco Moock <mo...@posteo.de> wrote:
> Am 20.06.2023 um 11:53:32 Uhr schrieb Ulli Horlacher:
>
>> Marco Moock <mo...@posteo.de> wrote:
>> > Am 20.06.2023 um 11:38:39 Uhr schrieb Ulli Horlacher:
>> >
>> >> Stefan Ram <r...@zedat.fu-berlin.de> wrote:
>> >> > Marco Moock <mo...@posteo.de> writes:
>> >> >>Wie kann ich erreichen, dass die find-Funktion {} mehrfach
>> >> >>genutzt werden kann?
>> >> >
>> >> > Hier führt
>> >> >
>> >> > find . -exec echo {} {} \;
>> >> >
>> >> > beispielsweise durchaus zur einer Ausgabe, in welcher der
>> >> > gefundene Pfad zwiefach in einer Zeile steht.
>> >> >
>> >> > find . -exec echo "ok" > {}.txt \;
>> >> >
>> >> > legt hingegen hier ".txt" an
>> >>
>> >> Klar, weil {} von find expandiert wird, wenn du es als Argument
>> >> uebergibst. Alles nach ">" sieht find aber nicht und kann es daher
>> >> auch nicht expandieren.
>> >
>> > Warum sieht find das nicht?
>>
>> Weil die Shell das gar nicht an find uebergibt.
>>
>>
>> > Es ist doch Teil des Arguments von -exec, oder?
>>
>> Oder! Nein.
>> Dein find-Kommando endet vor dem ">"
>
> Wie kommst das zustande?

Weil Shells nunmal so funktionieren. Schon immer. Also seit mehr als 50
Jahren.


> Baut find nicht aus den gefundenen Dateien passende Kommandos?

Ja. Aber dein exec Kommando lautet "echo ok", das ">" und alles was danach
kommt ist nicht mehr Bestandteil des Kommandos.

Du hast wohl eine voellig falsche Vorstellung wie UNIX shells funktionieren.


> Wie wird das sonst technisch umgesetzt?

Was "das"?

Marco Moock

unread,
Jun 20, 2023, 8:37:17 AM6/20/23
to
Wie verarbeitet find nun diesen Teil?
Ich dachte, dass das einfach nur in den Teil bei -exec die gefundenen
Dateien einsetzt.

Mir ist klar, dass Bash <>| entsprechend behandelt.
Nur ist mir der Bezug zu find noch unklar.

Ulli Horlacher

unread,
Jun 20, 2023, 8:51:58 AM6/20/23
to
Marco Moock <mo...@posteo.de> wrote:

>> >> >> > find . -exec echo "ok" > {}.txt \;
>> >> >> >
>> >> >> > legt hingegen hier ".txt" an
>> >> >>
>> >> >> Klar, weil {} von find expandiert wird, wenn du es als Argument
>> >> >> uebergibst. Alles nach ">" sieht find aber nicht und kann es
>> >> >> daher auch nicht expandieren.
>> >> >
>> >> > Warum sieht find das nicht?
>> >>
>> >> Weil die Shell das gar nicht an find uebergibt.
>> >>
>> >>
>> >> > Es ist doch Teil des Arguments von -exec, oder?
>> >>
>> >> Oder! Nein.
>> >> Dein find-Kommando endet vor dem ">"
>> >
>> > Wie kommst das zustande?
>>
>> Weil Shells nunmal so funktionieren. Schon immer. Also seit mehr als
>> 50 Jahren.
>>
>>
>> > Baut find nicht aus den gefundenen Dateien passende Kommandos?
>>
>> Ja. Aber dein exec Kommando lautet "echo ok", das ">" und alles was
>> danach kommt ist nicht mehr Bestandteil des Kommandos.
>
> Wie verarbeitet find nun diesen Teil?

Den Teil nach ">" also "{}.txt \;"?
Gar nicht.
find weiss davon nichts.
Das macht deine Shell.


> Ich dachte, dass das einfach nur in den Teil bei -exec die gefundenen
> Dateien einsetzt.

Ja, das tut es auch. Nur endet "der Teil" eben beim ">"


> Mir ist klar, dass Bash <>| entsprechend behandelt.
> Nur ist mir der Bezug zu find noch unklar.

Es gibt keinen Bezug.
Ich bezweifle daher dein "mir ist klar".
Du weisst wohl nicht, wie UNIX Shells prinzipiell funktionieren.

Kurz gesagt: Shells expandieren die Metazeichen
> < | ? * ( ) [ } { } ~ $ & \ ; ' "
und bei > < | & ; endet das jeweilige Kommando
Das Kommando wird mit den expandierten Argumente aufgerufen (fork).

In deinem Beispiel oben ist das also:

find . -exec echo ok

Das ">" und alles was danach kommt wird NICHT an find uebergeben, d.h. find
sieht und weiss davon NICHTS.
Da kannst du noch so oft mit dem Fuss aufstampfen, das hilft alles nichts
:-)

Stefan Reuther

unread,
Jun 20, 2023, 12:51:37 PM6/20/23
to
Am 20.06.2023 um 12:16 schrieb Marco Moock:
> Ich schaffe es nicht, mehrfach den gefundenen Dateinamen zu verwenden.
>
> find -name "xx*" -exec head -n 1 {} > {}-create \;
> resultiert in einer einzigen Datei namens {}-create.

Das Wort hinter '>' verarbeitet die aufrufende Shell, 'find' bekommt das
nie zu Gesicht.

> Variablen einbauen will ich eigentlich nicht.

Ohne geht es nicht.

find ... -exec sh -c 'head -n 1 "$1" > "$1"-create' find-sh {} ";"

('find-sh' wird als $0 an die aufgerufene 'sh' übergeben, die zu
verarbeitende Datei als $1.)


Stefan

Sieghard Schicktanz

unread,
Jun 20, 2023, 4:13:06 PM6/20/23
to
Hallo Ulli,

Du schriebst am Tue, 20 Jun 2023 12:51:57 +0000 (UTC):

> Marco Moock <mo...@posteo.de> wrote:
>
> >> >> >> > find . -exec echo "ok" > {}.txt \;

Mußte das sein?

...
> > Ich dachte, dass das einfach nur in den Teil bei -exec die gefundenen
> > Dateien einsetzt.
>
> Ja, das tut es auch. Nur endet "der Teil" eben beim ">"

Nicht ganz...
Das Umleitungszeichen und das darauffolgende "Wort" wird von der Shell
benutzt, der Rest des Aufrufs geht (hier) wieder an "find".
Das hat aber ein Problem bei einer Umleitung mittels "|" - da das keine
definierte Parameteranzahl hat, wird dem tatsächlich alles folgende
"verdächtige" als solche übergeben, was dann hier zu der überaus
vielsagenden Fehlermeldung "find: missing argument to `-exec'" führt...
...
> und bei > < | & ; endet das jeweilige Kommando

Nein, nur dannn, wenn die shell die Umleitung nicht eindeutig
identifizieren kann. D.h. der gegebene Aufruf

find . -exec echo "ok" > {}.txt \;

wird zerlegt in die Umleitung "> {}.txt" und den Programmaufruf
'find . -exec echo "ok" \;'

> Das Kommando wird mit den expandierten Argumente aufgerufen (fork).
>
> In deinem Beispiel oben ist das also:
>
> find . -exec echo ok

Das gäbe die o.g. Fehlermeldung von "find", weil sein "-exec" nicht korrekt
abgeschlossen ist.

> Das ">" und alles was danach kommt wird NICHT an find uebergeben, d.h.
> find sieht und weiss davon NICHTS.

Nein, nur das ">" und dessen Dateiargument benutzt die Shell, der Rest
bleibt Teil des Aufrufs.

> Da kannst du noch so oft mit dem Fuss aufstampfen, das hilft alles nichts
> :-)

Das ist alles in den "man pages" von "find" und der jeweiligen Shell
beschrieben zu finden.

--
(Weitergabe von Adressdaten, Telefonnummern u.ä. ohne Zustimmung
nicht gestattet, ebenso Zusendung von Werbung oder ähnlichem)
-----------------------------------------------------------
Mit freundlichen Grüßen, S. Schicktanz
-----------------------------------------------------------

Peter J. Holzer

unread,
Jun 20, 2023, 9:02:23 PM6/20/23
to
On 2023-06-20 10:16, Marco Moock <mo...@posteo.de> wrote:
> Ich schaffe es nicht, mehrfach den gefundenen Dateinamen zu verwenden.
>
> find -name "xx*" -exec head -n 1 {} > {}-create \;
> resultiert in einer einzigen Datei namens {}-create.
>
> Wie kann ich erreichen, dass die find-Funktion {} mehrfach genutzt
> werden kann?

Du musst von find aus eine Shell aufrufen:

find -name "xx*" -exec sh -c 'head -n 1 {} > {}-create' \;

hp

Peter J. Holzer

unread,
Jun 20, 2023, 9:02:23 PM6/20/23
to
On 2023-06-20 11:53, Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
> Marco Moock <mo...@posteo.de> wrote:
>> Am 20.06.2023 um 11:38:39 Uhr schrieb Ulli Horlacher:
>>
>>> Stefan Ram <r...@zedat.fu-berlin.de> wrote:
>>> > Marco Moock <mo...@posteo.de> writes:
>>> >>Wie kann ich erreichen, dass die find-Funktion {} mehrfach genutzt
>>> >>werden kann?
>>> >
>>> > Hier führt
>>> >
>>> > find . -exec echo {} {} \;
>>> >
>>> > beispielsweise durchaus zur einer Ausgabe, in welcher der
>>> > gefundene Pfad zwiefach in einer Zeile steht.
>>> >
>>> > find . -exec echo "ok" > {}.txt \;
>>> >
>>> > legt hingegen hier ".txt" an
>>>
>>> Klar, weil {} von find expandiert wird, wenn du es als Argument
>>> uebergibst. Alles nach ">" sieht find aber nicht und kann es daher
>>> auch nicht expandieren.

Nicht *alles*. Die Umleitung besteht nur aus »> {}.txt«. Alles danach
sind wieder Argumente:

% bash
hjp@puch:~/tmp$ echo a b > c d
hjp@puch:~/tmp$ cat c
a b d
hjp@puch:~/tmp$
exit


(in der Bourne Shell genauso, das ist kein Bashismus)

>> Es ist doch Teil des Arguments von -exec, oder?
>
> Oder! Nein.
> Dein find-Kommando endet vor dem ">"

Nope. Das find-Kommando ist

"find" "." "-exec" "echo" "ok" ";"

hp

Ulli Horlacher

unread,
Jun 21, 2023, 2:57:29 AM6/21/23
to
Peter J. Holzer <hjp-u...@hjp.at> wrote:

> Du musst von find aus eine Shell aufrufen:
>
> find -name "xx*" -exec sh -c 'head -n 1 {} > {}-create' \;

Raffiniert! :-)
Allerdings finde ich da meine Syntax eleganter:

with xx* : 'head -n 1 %f > %f-create'

Ausserdem sollte man bei find die {} in "" setzen, sonst passiert so was:

framstag@moep:/tmp: ll xx*
-rw-r--r-- framstag users 20 2023-06-21 08:45:33 'xx xx'

framstag@moep:/tmp: find -name "xx*" -exec sh -c 'echo {}; ll {}' \;
./xx xx
ll: cannot access './xx' - No such file or directory
ll: cannot access 'xx' - No such file or directory

framstag@moep:/tmp: find -name "xx*" -exec sh -c 'echo "{}"; ll "{}"' \;
./xx xx
-rw-r--r-- framstag users 20 2023-06-21 08:45:33 './xx xx'

Was aber auch nicht hilft, wenn der Dateiname selbst " enthaelt:

framstag@moep:/tmp: ll xx*
-rw-r--r-- framstag users 20 2023-06-21 08:52:20 'xx "xx"'

framstag@moep:/tmp: find -name "xx*" -exec sh -c 'echo "{}"; ll "{}"' \;
ll: cannot access './xx xx' - No such file or directory


Bei with funktioniert das out-of-the-box:

framstag@moep:/tmp: with xx* : 'echo %f; ll %f'
xx "xx"
-rw-r--r-- framstag users 20 2023-06-21 08:45:33 'xx "xx"'

Tim Landscheidt

unread,
Jun 21, 2023, 6:54:54 AM6/21/23
to
Prinzipiell könnte man das Problem ja auch mit seds „w“-Be-
fehl (bzw. GNU seds „W“-Befehl) lösen. Aber dieser erfordert
den Dateinamen als Parameter, und sowohl die GNU-Dokumenta-
tion als auch
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html
schweigen sich dazu aus, wie man Dateinamen mit newlines,
Leerzeichen, Backslashes, etc. benutzen kann.

Ist das generell/portabel nicht möglich?

Tim

Helmut Waitzmann

unread,
Jun 21, 2023, 2:22:36 PM6/21/23
to
"Peter J. Holzer" <hjp-u...@hjp.at>:
> On 2023-06-20 10:16, Marco Moock <mo...@posteo.de> wrote:
>> Ich schaffe es nicht, mehrfach den gefundenen Dateinamen zu
>> verwenden.
>>
>>
>> find -name "xx*" -exec head -n 1 {} > {}-create \;
>> resultiert in einer einzigen Datei namens {}-create.
>>
>> Wie kann ich erreichen, dass die find-Funktion {} mehrfach genutzt
>> werden kann?
>>
>
> Du musst von find aus eine Shell aufrufen:
>

Ja, aber nicht so:


> find -name "xx*" -exec sh -c 'head -n 1 {} > {}-create' \;


Sondern so:


find -name 'xx*' \
-exec sh -c 'head -n 1 "$1" > "$1"-create' sh '{}' \;


Den Grund sieht man an folgendem Beispiel, in einem leeren
Verzeichnis ausgeführt:

# Zuerst werden besondere Dateinamen erzeugt:
touch -- Apostroph\' Anfuehrungszeichen\" Backslash\\ &&
# Dann wird find darauf losgelassen:
find . -exec sh -c -- 'ls -dF -- {}' \;


Das aufgerufene Shell scheitert mit der an ihn übergebenen
Kommandozeile, weil „find“ den gefundenen Dateinamen jeweils
unverändert in die Kommandozeile spuckt, ohne Rücksicht darauf,
dass im Dateinamen Zeichen enthalten sind, die vor dem
Kommandozeilen‐Parser des aufgerufenen Shells geschützt werden
müssen.  Und das tut „find“ deshalb so rücksichtslos, weil es
nicht weiß – denn es kann es nicht wissen –, dass die gefundenen
Dateinamen hier in eine „sh“‐Kommandozeile gespuckt werden und
deshalb zuerst mit einem entprechenden Quoting versehen werden
müssten.  Deshalb kann man in „find“ so ein Quoting für das Shell
auch nicht einbauen.


Gegenprobe:  Das folgende Kommando wird funktionieren:


find . -exec sh -c -- 'ls -dF -- "$@"' sh '{}' \;


Und zwar funktioniert es deshalb, weil die gefundenen Dateinamen
hier nicht in eine Shell‐Kommandozeile gespuckt, sondern dem
Shell als positional parameters übergeben werden.  Deshalb kann
das von „find“ gestartete Shell darauf über „"$@"“ zugreifen. 
(In diesem Fall ist es immer genau ein Parameter, deshalb könnte
man in der Kommandozeile statt „"$@"“ auch „"$1"“ schreiben.)


Es läuft hier und immer wieder an vielen anderen Stellen darauf
hinaus:  Wer mit dem Shell fortgeschritten umgehen will, muss die
richtige Verwendung der Shell‐Option „-c“ beherrschen.  Und die
sieht idealerweise so aus:


sh -c -- 'hier kommt eine Kommandozeile ohne variable Teile' \
sh Hier kommen die positional parameters, gerne variabel.


Es kann auch Fälle geben, in denen man nicht darum herum kommt,
dem Shell eine variable, also vom Aufrufer zur Laufzeit zu
bestimmende Kommandozeile zu übergeben.  Dann muss man allerdings
die variablen Teile so mit Shell‐Quoting‐Mechanismen („''“, „""“
und „\“) bearbeiten, ehe man sie in die Kommandozeile spuckt,
dass sie für den Kommandozeilen‐Parser des aufgerufenen Shells
passen.  Leider stellt der POSIX‐Standard dafür (noch) nichts zur
Verfügung.  (Das ins „bash“ eingebaute „printf“‐Kommando und auch
GNU‐printf halten dafür das Formatierungselement „%q“ bereit.)


--
Hat man erst verstanden, wie Unix funktioniert, ist auch
das Shell-Handbuch kein Buch mit sieben Siegeln mehr.

Helmut Waitzmann

unread,
Jun 21, 2023, 2:22:38 PM6/21/23
to
Marco Moock <mo...@posteo.de>:
> Am 20.06.2023 um 11:38:39 Uhr schrieb Ulli Horlacher:
>
>> Stefan Ram <r...@zedat.fu-berlin.de> wrote:
>> > Marco Moock <mo...@posteo.de> writes:
>> >>Wie kann ich erreichen, dass die find-Funktion {} mehrfach genutzt
>> >>werden kann?
>> >
>> > Hier führt
>> >
>> > find . -exec echo {} {} \;
>> >
>> > beispielsweise durchaus zur einer Ausgabe, in welcher der
>> > gefundene Pfad zwiefach in einer Zeile steht.
>> >
>> > find . -exec echo "ok" > {}.txt \;
>> >
>> > legt hingegen hier ".txt" an
>>
>> Klar, weil {} von find expandiert wird, wenn du es als Argument
>> uebergibst. Alles nach ">" sieht find aber nicht und kann es daher
>> auch nicht expandieren.
>>

[Es geht um die Shell‐Kommandozeile


find . -exec echo "ok" > {}.txt \;

]


> Warum sieht find das nicht?
>
> Es ist doch Teil des Arguments von -exec, oder?
>

Es ist nicht Teil der Aufrufparameter von „find“.  Im Einzelnen:


Ein‐ oder Ausgabeumlenkungen führt das Shell aus, ehe es das
Kommando (hier: das sogenannte simple command „find …“) überhaupt
startet.  Deshalb ist es das Shell und nicht „find“, das den Teil
der genannten Kommandozeile, „> {}.txt“, ausführt.


Der Teil teilt ihm mit, dass es für die Standardausgabe eine
Ausgabeumlenkung auf die Datei „{}.txt“ vornehmen soll.


Wenn es die (und weiteres) vorgenommen hat, startet es
schließlich das Programm „find“ mit den Parametern „.“, „-exec“,
„echo“, „ok“ und „;“.


Wie das Shell im einzelnen vorgeht, wenn es ein simple command
ausführt, wird in
<https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01>
beschrieben.

Sieghard Schicktanz

unread,
Jun 21, 2023, 4:13:06 PM6/21/23
to
Hallo Stefan,

Du schriebst am 20 Jun 2023 19:42:33 GMT:

> >$ bash -x
> >$ find . -exec echo a >tmp.tmp \;
> >+ find . -exec echo a ';'

Warum rufst Du eine weitere _interaktive_ Shell dafür auf?

> Um die neue Shell wieder zu verlassen, verwendet man natürlich "exit".
> Jedoch kann man statt "bash -x" auch "set -x" verwenden. Dann braucht
> man keine neue Shell. Dies sollte man vermutlich mit "set +x" wieder
> rückgängig machen können.

Ja, man kann sich die Sache mit sowas beliebig kompliziert machen.
Reicht Dir ein Aufruf

bash -xc "find . -exec echo a >tmp.tmp \;"

nicht?

Peter J. Holzer

unread,
Jun 22, 2023, 8:11:02 AM6/22/23
to
On 2023-06-21 18:52, Sieghard Schicktanz <Sieghard....@SchS.de> wrote:
> Hallo Stefan, Du schriebst am 20 Jun 2023 19:42:33 GMT:
>
>> >$ bash -x
>> >$ find . -exec echo a >tmp.tmp \;
>> >+ find . -exec echo a ';'
>
> Warum rufst Du eine weitere _interaktive_ Shell dafür auf?

1. Weil man in dieser Shell dann verschiedene Kommandos ausprobieren
kann.

2. Weil man sich dann nur mit dem Verhalten einer Shell beschäftigen
muss und nicht von zwei.

> Ja, man kann sich die Sache mit sowas beliebig kompliziert machen.
> Reicht Dir ein Aufruf
>
> bash -xc "find . -exec echo a >tmp.tmp \;"
>
> nicht?


Da muss man jetzt unterscheiden, was die Shell, in der man arbeitet, mit
der Zeile macht (z.B.: Wird ein \ innerhalb von "" interpretiert oder
nicht?) und was die aufgerufene Shell dann macht. Das macht es nicht
einfacher, sondern komplizierter.

hp

Peter J. Holzer

unread,
Jun 22, 2023, 8:16:33 AM6/22/23
to
On 2023-06-21 17:51, Helmut Waitzmann <nn.th...@xoxy.net> wrote:
> "Peter J. Holzer" <hjp-u...@hjp.at>:
>> On 2023-06-20 10:16, Marco Moock <mo...@posteo.de> wrote:
>>> Ich schaffe es nicht, mehrfach den gefundenen Dateinamen zu
>>> verwenden.
>>>
>>>
>>> find -name "xx*" -exec head -n 1 {} > {}-create \;
>>> resultiert in einer einzigen Datei namens {}-create.
>>>
>>> Wie kann ich erreichen, dass die find-Funktion {} mehrfach genutzt
>>> werden kann?
>>>
>>
>> Du musst von find aus eine Shell aufrufen:
>>
>
> Ja, aber nicht so:
>
>
>> find -name "xx*" -exec sh -c 'head -n 1 {} > {}-create' \;
>
>
> Sondern so:
>
>
> find -name 'xx*' \
> -exec sh -c 'head -n 1 "$1" > "$1"-create' sh '{}' \;
>

Ja, stimmt. Ist mir nach dem Absenden auch aufgefallen, dass man nicht
in einem Verzeichnis mit "gefährlichen" Filenamen aufrufen sollte. Aber
dann habe ich Dein anderes Posting gesehen und auf ein Followup
verzichtet.

hp

Helmut Waitzmann

unread,
Jun 22, 2023, 4:17:17 PM6/22/23
to
r...@zedat.fu-berlin.de (Stefan Ram):
> r...@zedat.fu-berlin.de (Stefan Ram) writes:
>>$ bash -x
>>$ find . -exec echo a >tmp.tmp \;
>>+ find . -exec echo a ';'
>
> Um die neue Shell wieder zu verlassen, verwendet man natürlich
> "exit". Jedoch kann man statt "bash -x" auch "set -x" verwenden.
> Dann braucht man keine neue Shell. Dies sollte man vermutlich
> mit "set +x" wieder rückgängig machen können.
>

Genau.  Und wenn einem das zu blöde ist, Einstellungen wie „set
-x“ wieder zurücknehmen oder ein extra gestartetes neues Shell
beenden zu müssen, kann man auch einfach runde Klammern verwenden:


( set -x && find . -exec echo a >tmp.tmp \; )


Die runden Klammern erzeugen ein subshell environment; und daraus
kann nichts in die Aufruferumgebung herauswirken.

0 new messages