Re: mehrere Dateinamen in einer Variablen an Programm übergeben
Am Dienstag, 27. August 2013, 20:43:16 schrieb Matthias Meyer:
> Hallo,
Hi Matthias,
> Ich habe ein Problem mit einem bash-script dem ich mehrere Dateinamen als
> Parameter übergeben will und die Dateinamen können natürlich BLANKS
> enthalten.
> Das test-script:
> #$!/bin/bash
> while test $# -gt 0; do
> echo :$1:; shift
> done
> exit
>
> Das funktionert wenn ich die Dateinamen direkt angebe:
> %scripts/test 'file1' 'file name'
>
> :file1:
>
> :file name:
> Wenn ich die Dateinamen aber in einer Variablen halte dann geht es nicht
> mehr
>
> filenames="'file1' 'file name'"
> %scripts/test $filenames
>
> :'file1':
> :'file:
>
> :name':
Für Diagnose-Zwecke:
martin@merkaba:~ -> cat test
#$!/bin/bash
echo "Anzahl: $#"
echo "Zeile: $*"
while test $# -gt 0; do
echo :$1:; shift
done
exit
Okay, auch mit Escaping geht es nicht:
martin@merkaba:~ -> filenames="\"file1\" \"file name\""
In der Bash:
martin@merkaba:~ -> ./test "file1" "file name"
Anzahl: 2
Zeile: file1 file name
:file1:
:file name:
martin@merkaba:~ -> ./test $filenames
Anzahl: 3
Zeile: "file1" "file name"
:"file1":
:"file:
:name":
Das heißt, die Bash löst das Quoting nicht auf, wenn die Argumente als
Variable daher kommen. Interessant.
Hier würde jetzt
martin@merkaba:~ -> for DATEI in "file1" "file name" ; do echo "$DATEI"; done
file1
file name
funktionieren.
Das funktioniert bei direkter Übergabe aber nicht, da die Bash das Quoting
dann auflöst und die Anführungszeichen dann nicht mehr in $* mit drinnen sind.
Und warum die Bash sich so verhält, steht wahrscheinlich irgendwo in der
wunderbaren Manpage der Bash.
Die Z-Shell verhält sich anders:
martin@merkaba:~ -> zsh
martin@merkaba:~> ./test "file1" "file name"
Anzahl: 2
Zeile: file1 file name
:file1:
:file name:
martin@merkaba:~> filenames="\"file1\" \"file name\""
martin@merkaba:~> ./test $filenames
Anzahl: 1
Zeile: "file1" "file name"
:"file1" "file name":
Sie betrachtet offenbar den Variablen-Inhalt als *ein* Argument, IMHO
konsistenter, sinniger als das, was die Bash macht.
> Wie kann ich eine Liste von Dateinamen in einer Variablen sammeln und dann
> an ein anderes Programm übergeben?
Wenn Du immer mit einer Variable arbeitest, funktioniert das For-Schleifen-
Dingens, zumindest mit der Bash.
Irgendwie zeigt mir obiges Beispiel mal wieder, dass ich komplexere Dinge
nicht als Shell-Skript realisieren möchte.
Allerdings hängt das gar nicht mal davon ab. Ein Ruby-Skript macht genau den
gleichen Müll. Es bekommt das Zeug schon so von der Bash:
martin@merkaba:~ -> cat ./test.rb
#!/usr/bin/env ruby
puts $*
martin@merkaba:~ -> ./test.rb eins zwei
eins
zwei
martin@merkaba:~ -> ./test.rb $filenames
"file1"
"file
name"
Das ganze in der Z-Shell:
martin@merkaba:~> filenames="\"file1\" \"file name\""
martin@merkaba:~> ./test.rb $filenames
"file1" "file name"
Wieder als ein Argument.
So mal sehen, vielleicht hat ja jemand eine logische Erklärung für das
Verhalten der Bash. Das Verhalten der Z-Shell leuchtet mir ja noch irgendwie
ein.
Es läßt sich mit der Bash auch hinbekommen:
martin@merkaba:~ -> ./test.rb "$filenames"
"file1" "file name"
LOL.
Jetzt lasse ich das erstmal sitzen. Die Erklärung ist bestimmt ganz logisch :)
– innerhalb von Shell-Logik :)
Ciao,
--
Martin 'Helios' Steigerwald - http://www.Lichtvoll.de
GPG: 03B0 0D6C 0040 0710 4AFA B82F 991B EAAC A599 84C7
Reply to: