2017-12-25 7 views
1

ich dieses kleine Skript:Umleitung auf eine Variable hat seltsames Verhalten

#!/bin/bash 
for file in "$(ls | grep -v $0)";do 
     cat $file > "${file}-test" 
done 

Auf diesem Verzeichnis:

total 40 
-rwxr-xr-x 1 root root 783 Dec 11 09:19 appendToLog.sh 
-rwxr-xr-x 1 root root 3995 Dec 11 13:22 con2dd.py 
-rwxr-xr-x 1 root root 362 Dec 11 13:26 dd.py 
-rw-r--r-- 1 root root 566 Dec 11 13:26 dd.pyc 
-rw-r--r-- 1 root root 18558 Dec 25 11:24 moshe.log 
-rw------- 1 root root  0 Dec 11 09:20 nohup.out 
-rwxr-xr-x 1 root root 88 Dec 25 11:28 task.sh 
-rwxr-xr-x 1 root root 560 Dec 11 10:33 test.py 

Nevermind, dass ich das mit cp erreichen kann, ich, warum diese genau verstehen will produziert diese Datei:

-rw-r--r-- 1 root root 24912 Dec 25 11:28 appendToLog.sh?con2dd.py?dd.py?dd.pyc?moshe.log?nohup.out?task.sh?test.py-test 

Und sonst nichts.

Antwort

2

Das Problem ist das Parsen Ausgabe von ls einfach falsch ist (siehe Why you shouldn't parse the output of ls(1), Dateinamen in Unix können fast jedes Sonderzeichen einschließlich Leerzeichen, Zeilenumbrüche, Kommata, Rohr Symbole haben. Sein, weil Sie die Ausgabe von ls in einem Konstrukt zitiert haben haben Sie eine einzige Liste aller als eine Zeichenfolge verkettet Dateien im Wert von "${file}-test" die nicht recht ist, was Sie tun wollte.

Beachten Sie auch, wie ls Ihre Dateinamen Daten manchmal verstümmelt (in unserem Fall, es drehte das \n Zeichen zwischen den Wörtern in ein ? Fragezeichen (könnte ein Zeichen anzeigen, das nicht displ sein kann) ayed).

Verwenden Sie einfach die Glob-Erweiterung in bash, um die Dateien aufzulisten und Aktionen auf ihnen.

for f in *; do 
    [[ -e $f ]] || continue 
    ... 
done 

Das heißt, Sie könnten wahrscheinlich einige nicht druckbare Zeichen auf Zeilenende (zB. CRLF importiert rom Windows)

Run cat -A scriptname es wird Ihnen zeigen alle Zeichen in Ihrem Skript . Dann können Sie in ein unixartiges Format konvertieren, das dos2unix scriptname ausführt.