variable

hashier

Well-Known Member
Hi,


weis nicht was ich hier sinnvolles als Threadtitel angeben soll und weis auch nicht nach was ich bei google oder hier im Board suchen sollte, weil es sicherlich schonmal beantwortet wurde, aber keine Ahnung nach was ich suchen muss.


Problem:


Ich will in einer Variable Dateien speichern (Teilweise mit Leerzeichen) und ich moechte dann auf diese Files zugreifen.

Sowas hab ich probiert:


Code:
[0306]jonas@envy ~ $ export FILES="chris_remixes.pls test.pls a\ b"
[0306]jonas@envy ~ $ ls -l $FILES
ls: a\: No such file or directory
ls: b: No such file or directory
-rw-r--r--  1 jonas users 1386 Aug 12 02:34 chris_remixes.pls
-rw-r--r--  1 jonas users  200 Aug 12 02:36 test.pls
[0306]jonas@envy ~ $ export FILES="chris_remixes.pls test.pls 'a b'"
[0306]jonas@envy ~ $ ls -l $FILES
ls: 'a: No such file or directory
ls: b': No such file or directory
-rw-r--r--  1 jonas users 1386 Aug 12 02:34 chris_remixes.pls
-rw-r--r--  1 jonas users  200 Aug 12 02:36 test.pls
[0306]jonas@envy ~ $ export FILES='chris_remixes.pls test.pls "a b"'
[0307]jonas@envy ~ $ ls -l $FILES
ls: "a: No such file or directory
ls: b": No such file or directory
-rw-r--r--  1 jonas users 1386 Aug 12 02:34 chris_remixes.pls
-rw-r--r--  1 jonas users  200 Aug 12 02:36 test.pls
[0307]jonas@envy ~ $


Wie muss es richtig sein?
 
hashier schrieb:
weis nicht was ich hier sinnvolles als Threadtitel angeben soll und weis auch nicht nach was ich bei google oder hier im Board suchen sollte, weil es sicherlich schonmal beantwortet wurde, aber keine Ahnung nach was ich suchen muss.
Wie man Fragen richtig stellt beantwortet zumindest diese Frage.
Ich will in einer Variable Dateien speichern (Teilweise mit Leerzeichen) und ich moechte dann auf diese Files zugreifen.

Sowas hab ich probiert:
[0306]jonas@envy ~ $ export FILES="chris_remixes.pls test.pls a\ b"
Böse Falle. Die Standard-Shells kennen keine strukturierten Variablen. Leerzeichen sind Field Separator, weshalb a\ b automatisch beim Field Separator zerlegt wird. Macher Shell-Experte wird jetzt mit Hinweisen kontern, wie man diese Einschränkung der Shell umgehen kann (Fieldseparator auf ein nicht im Variableninhalt vorkommendes Zeichen setzen), oder welche Shell dieses Problem elegant löst.

Ich empfehle stattdessen eine andere Skriptsprache zu verwenden. Perl, Python oder PHP sind geeignet, solche Dinge zu programmieren und verursachen wesentlich weniger Kopfschmerz bei der Problemlösung. Zudem bieten Sie wesentlich bessere Debug-Möglichkeiten als die Shell.
 
Achtung, böser Hack:
Code:
> touch ABC UVW\ XYZ
> FILES="ABC UVW\ XYZ"
> eval ls -ln $FILES
-rw-r--r--  1 500  100  0 12 Aug 12:17 ABC
-rw-r--r--  1 500  100  0 12 Aug 12:17 UVW XYZ
Je nach dem, welche Sonderzeichen aber in $FILES vergraben werden, kann das bei eval(1) ganz schön in die Hose gehen. Das ist einfach der Nachteil von Shell-Scripts. Wenn du sicherheitsrelevante Dinge tun willst, dann halte dich an den Rat von cheasy und suche dir eine "richtige" Programmiersprache. Wenn es nur ein schneller Hack sein soll, dann kann man das auch mit der Shell machen.
 
Mit eval hatte ich auch kurz proibert, aber auch nicht zum ziel gekommen.

Das script ist nicht lang, es macht eigentlich nur folgendes:

Eine xmms.pls datei zu nehmen.
Alle Zeilen rausholen in denen mp3 vorkommt, dann alles wegschneiden was nicht zum filenamen gehoert.

Dann steht in jeder Zeile ein mp3 file.

Diese Zeilen sollte er einfach hinterainnder haengen, aber natuerlich jedes file mit " " umschliessen.


Damit ich am ende dann einen befehl wie
rsync $MP3s zielrechner:
ausfuehren kann.

Sollte eigentlich nur ganz fix ein script sein, damit ich meine playliste auf nen anderen Rechner oder Memorystick kloppen kann.

Ist anscheind doch nicht so einfach zu realisieren.

Was sollte man lernen? Python? Das hoert man ja von Tag zu Tag mehr.
Perl hingegen hoert man fast garnichtmehr.
 
Code:
echo "Dateiname der Playliste: "
read PLAYLIST

IFS="
"

for DATEI in $(basename $(grep '.mp3$' "$PLAYLIST"))
do
  echo -n "\"$DATEI\" "
done
Wie du das dann jeweils an das Programm zum Synchronisieren übergibst, ist jetzt deine Aufgabe. Du kannst zum Beispiel die gesamte for-Schleife an ein anderes Programm weiterpipen, indem du hinter dem done eine Pipe anhängst. Da mußt du eben mal sehen, wie du das ganze beispielsweise an rsync(1) übergeben kannst. Dieses Problem hast du mit Perl (oder jeder anderen Programmiersprache) aber im Prinzip dann auch.
 
Ein Pipe hinter done haengen bringt leider garnichts.


Code:
  while [ $AKT -le $ZEILEN ]
    do
    #URL=\'`sed -n ${AKT}p $WRKFILE`\'" "
    URL=`sed -n ${AKT}p $WRKFILE`
    #URLs=${URLs}${URL}
    URL2=`echo -n "\"$URL\" "`
    #ls -l "$URL2"
    echo "$URL2"
    AKT=`expr $AKT + 1`
  done 
  #$CMD $URLs

sieht aber schon sehr vielversprechend aus:

"/hdb1/mp3/VA_-_Firstclass_-_Best_of_2004-2005-2CD-2004-ALC/108-glamarama_-_girls_just_wanna_havefun-alc.mp3"
"/hdb1/mp3/new/Uniting Nations - Out Of Touch.mp3"
"/hdb1/mp3/new/Thomas Falcon - High Again.mp3"

Aber leider, wenn ich statt echo "$URL2" ein ls "$URL2" eintrage kommt nur:

ls: "/hdb1/mp3/new/Uniting Nations - Out Of Touch.mp3" : No such file or directory
ls: "/hdb1/mp3/new/Thomas Falcon - High Again.mp3" : No such file or directory
 
Erstens: Poste bitte das komplette Skript. So weiß man überhaupt nicht, was du da überhaupt zu veranstalten versuchst.

Zweitens: Du willst eval(1) verstehen lernen oder dir eine andere Programmiersprache suchen.

Drittens: Wenn es immer noch darum geht, ein paar MP3s aus einer Playlist zu holen, dann ist das, was du da machst, extrem umständlich und ineffizient.

Vielleicht solltest du einfach komplett beschreiben, was du vor hast, statt nur Bruchstücke zu liefern.
 
statt for i in ... ist bei elementen mit leerzeichen folgendes ganz brauchbar: cat ... | while read i; do ... "$i"; done
 
0815Chaot schrieb:
Code:
echo "Dateiname der Playliste: "
read PLAYLIST

IFS="
"

for DATEI in $(basename $(grep '.mp3$' "$PLAYLIST"))
do
  echo -n "\"$DATEI\" "
done
damit machst du ja ein basename auf den kompletten grep output..

Code:
grep '.mp3$' "${PLAYLIST}" | while read file; do ... "$(basename ${file})"; done
 
Da ich kein rsync installiert habe, ist folgender Beispielcode mit ls:
Code:
echo "Dateiname der Playliste: "
read PLAYLIST

IFS="
"

eval ls $(for DATEI in $(grep '.mp3$' "$PLAYLIST" | cut -d= -f2-)
          do
            echo -n "\"$DATEI\" "
          done)
Ausgabe:
Code:
Dateiname der Playliste:
test.pls
ls: /hdb1/mp3/VA_-_Firstclass_-_Best_of_2004-2005-2CD-2004-ALC/108-glamarama_-_girls_just_wanna_havefun-alc.mp3: No such file or directory
ls: /hdb1/mp3/new/Thomas Falcon - High Again.mp3: No such file or directory
ls: /hdb1/mp3/new/Uniting Nations - Out Of Touch.mp3: No such file or directory
Funktioniert also, sofern rsync mehrere Quelldateien auf einer Kommandozeile akzeptiert.
 
hashier schrieb:

Warum einfach, wenn's auch kompliziert geht?

Du hast eine Datei und willst daraus fuer alle Zeilen, die mit "File[[:digit:]]\{1,\}=" beginnen, ein Kommando fuer die hinter dieser Regexp stehende Datei aufrufen, richtig?

Code:
sed 's/^File[[:digit:]]\{1,\}=\(.*\)/ls '\''\1'\''/p;d' test.pls | sh

Das waere jetzt beispielhaft mit ls als Kommando. Fuer andere Aktionen nimmt man halt entsprechend andere Kommandos, z.B.
Code:
rsync '\''\1'\'' foobar:
.
 
Zurück
Oben