Vorgehensweise bei Ordnern/Dateien mit Leerzeichen bzw. Sonderzeichen



  • Ok, hier ein komplettes Beispiele. Das sollte mein Problem verständlich machen 🙂

    /test # mkdir "test ordner 1"
    /test # mkdir "test ordner 2"
    /test # mkdir "test ordner 1/1"
    /test # mkdir "test ordner 1/2"
    /test # mkdir "test ordner 1/3"
    /test # touch "test ordner 1/a"
    /test # touch "test ordner 1/b"
    /test # touch "test ordner 1/c"
    /test # touch c
    /test # mv c "test ordner 1/"
    /test # 
    /test # FROM="test ordner 1"
    /test # TO="test ordner 2"
    /test # cp -Rp "$FROM/*" "$TO"
    cp: cannot stat 'test ordner 1/*': No such file or directory
    /test #
    

    War doch alles richtig? Es war in Hochkommata und sogar in Variablen. Ohne Hochkommata liefe es auf ein paar mehr Fehlermeldungen hinaus und letzteres macht keinen Unterschied.

    Wenn ich die Leerzeichen jetzt mit einem Backslash maskiere (sed), dann funktioniet es perfekt (ob Variable oder nicht). Damit wäre das Problem gelößt. Danke so weit.

    Jetzt stellt sich nur noch die Frage, ob das nur auf der Shell vom ESXi so ist (wobei es laut Google nicht nur bei VMware so zu sein scheint), sonst hätte ich gefragt, warum man die Leerzeichen nur bei ls, cp und grep maskieren muss und bei dirname, basename, cat, cut mkdir, rm, touch, source, sed, kill und chmod nicht. Diese Inkonsistenz regt mich ziemlich auf. Warum nicht einheitlich alles maskieren müssen?

    Schöne Grüße



  • Achja, natürlich muss das so aussehen:

    /test # cp -Rp test\ ordner\ 1/* test\ ordner\ 2
    

    Denn so funktioniert es auch nicht:

    /test # cp -Rp "test\ ordner\ 1/*" "test\ ordner\ 2"
    cp: cannot stat 'test\ ordner\ 1/*': No such file or directory
    

    Problematisch scheinen also die Hochkommata zu sein. Gibt es zu diesen eine Alternative, welche das maskieren der Leerzeichen unnötig macht?



  • cp -Rp "$FROM"/* "$TO"
    

    Oder gleich

    rsync -a "$FROM"/ "$TO"
    


  • AnonFragesteller schrieb:

    Problematisch scheinen also die Hochkommata zu sein. Gibt es zu diesen eine Alternative, welche das maskieren der Leerzeichen unnötig macht?

    Wie oben schon beschrieben: Leerzeichen müssen nicht maskiert werden, wenn der Pfad in einer Variablen steht. Du kannst einfach direkt "$foo" schreiben, völlig egal, ob $foo Leerzeichen enthält oder nicht.

    Leerzeichen escapen musst du nur, wenn du solche Pfade irgendwo hartkodierst.



  • Nennt mich hartnäckig, aber so schnell geb ich mich nicht geschlagen.
    Dass hartkodiertes maskiert werden muss, wusste ich nicht und finde es gut, das zu jetzt wissen. Danke.

    Aber nützen tut das auch nichts. Hier ein Beispiel ohne hartcodierter Pfade & Co. Gleich vorweg: es funktioniert nicht.

    #!/bin/sh
    
    ls -d * | while read ii
    do
            if [ ! -d $ii ]; then
                    continue;
            fi
    
            mkdir $ii-2
            cp -Rp $ii/* $ii-2/
    done
    

    Ergebnis:

    /test # ll
    drwxr-xr-x    1 root     root                512 Jun  1 07:55 test ordner 1
    drwxr-xr-x    1 root     root                512 Jun  1 08:52 test ordner 2
    -rwxr-xr-x    1 root     root                140 Jun  4 07:08 test.sh
    /test # ./test.sh
    sh: ordner: unknown operand
    cp: cannot stat '1/*': No such file or directory
    sh: ordner: unknown operand
    mkdir: cannot create directory 'test': File exists
    mkdir: cannot create directory 'ordner': File exists
    cp: cannot stat '2/*': No such file or directory
    /test # ll
    drwxr-xr-x    1 root     root                512 Jun  1 07:55 test ordner 1
    drwxr-xr-x    1 root     root                512 Jun  1 08:52 test ordner 2
    -rwxr-xr-x    1 root     root                140 Jun  4 07:08 test.sh
    drwxr-xr-x    1 root     root                512 Jun  4 07:12 test
    drwxr-xr-x    1 root     root                512 Jun  4 07:12 ordner
    drwxr-xr-x    1 root     root                512 Jun  4 07:12 2-2
    drwxr-xr-x    1 root     root                512 Jun  4 07:12 1-2
    /test #
    

    Und nun kommt wieder ihr 😃

    Btw. in meinem Script habe ich jetzt alle Änderungen wieder rückgängig gemacht. Denn nachdem ich alles habe automatisch maskieren lassen, verweigerten selbst Kommandos wie 'mv' den Dienst, welche zuvor sehr gut mit unmaskierten UND maskierten Leerzeichen klar kamen (Klartext & Variablen). Natürlich alles schön mit Echo ausgeben lassen und via C&P getestet. Von Hand kopiert und ausgeführt lief es plötzlich..... Liegt es vllt. nur an VMware ESXi 5? Ich weiß es nicht, aber eine Lösung muss es geben 😡

    Schöne Grüße,
    AnonFragesteller



  • AnonFragesteller schrieb:

    #!/bin/sh
    
    ls -d * | while read ii
    do
            if [ ! -d "$ii" ]; then
                    continue;
            fi
    
            mkdir "$ii-2"
            cp -Rp "$ii"/* "$ii-2"/
    done
    

    Versuchs mal so.

    Wobei ich mich frage, warum Du mit -d fragst, ob das ein Verzeichnis ist, wenn Du doch ls schon anweist, nur Verzeichnisse auszugeben.

    Und denk daran, dass Du auch die Verzeichnisse '.' und '..' bekommst. Die könntest Du beispielsweise mit grep zwischen ls und while noch raus filtern.



  • Bei deinem Beispiel würde das passieren:

    cp: cannot stat '[...]': No such file or directory
    

    Ich frage danach noch mit -d ab, weil mir ls -d auch Dateien lieferte.

    Ok, ich breche dann mal an dieser Stelle ab und bedanke mich für die Antworten 🙂
    Das Backupscript läuft nun perfekt, so lange keine Leerzeichen im Spiel sind - auch nach einem Patch oder Neustart (auto. Reinstall des Script incl. GhettoVCB).

    Und was haben wir gelernt? Arbeite nie mit der ESXi Shell... oder dem ESXi vim -,-



  • Na siehst Du - mein Skript ist schon bis zum cp gekommen. Damit ist doch das eigentliche Problem gelöst. Also das Problem mit Leerzeichen. Das nächste Problem ist, dass Du ein leeres Verzeichnis hast. Da funktioniert das "foo/*" nicht, da es nichts zum expandieren gibt.

    Und was lernen wir daraus: Man sollte in einer ruhigen Minute mal die man page der shell lesen.

    Und überhaupt: was hat das ganze mit ESXi Shell oder gar vim zu tun 😕 .



  • Welche manpages? Die gibt es beim ESXi nicht.
    Und doch, in dem Ordner befanden sich Dateien.

    Wenn nicht nur ihr der Meinung seit, dass es eigentlich gehen müsste, es aber nicht geht, egal wie man es macht (siehe Beispiele von mir), dann läge der Verdacht nahe, dass es an der ESXi-Shell liegt.

    Und was Vim angeht... nun, ich habe wärend meiner gesamten Ausbildung mit (g)Vim gearbeitet, auch Daheim - und die Variante vom ESXi ist einfach nur grausig.

    Schöne Grüße,
    AnonFragesteller



  • WICHTIGER LINK

    ➡ ➡ ➡ Manpages, Manpages, Manpages!

    Ich bin immer noch der Ansicht, dass das ein Job für rsync ist. Ansonsten sei angemerkt, dass

    cp -RpT "$ii" "$ii-2"
    

    macht, was du willst, ohne irgendwelche Expansionsprobleme zu haben. Das lässt sich mit anderen Tools kombinieren, etwa

    find . -mindepth 1 -maxdepth 1 -type d -exec cp -RpT '{}' '{}-2' \;
    

    um Verzeichisse herauszupicken.

    So oder so musst du damit umgehen, dass du auf die Dauer Verzeichnisse der Form foo-2-2-2-2 bekommst, deren Inhalt nicht trivial vorhersagbar ist.


Anmelden zum Antworten