UlfZibis
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3021
Wohnort: Köln
|
Hallo, bei der Ausführung des folgenden Skripts unter debug/test_spaces.sh 1
2
3
4
5
6
7
8
9
10
11
12
13 | #!/bin/bash
file="CYD_1005 (Kopie).jpg"
echo file: "${file}"
input="debug/${file}"
echo "input: ${input}"
echo "$(ls -l \"${input}\")"
ls -l \"${input}\"
input="\"debug/${file}\""
echo "input: ${input}"
echo "ls -l ${input}"
ls -l ${input}
# Kontrolle:
ls -l "debug/CYD_1005 (Kopie).jpg"
|
bekomme ich folgende Ausgabe: $ debug/test_spaces.sh
file: CYD_1005 (Kopie).jpg
input: debug/CYD_1005 (Kopie).jpg
ls: Zugriff auf '"debug/CYD_1005' nicht möglich: Datei oder Verzeichnis nicht gefunden
ls: Zugriff auf '(Kopie).jpg"' nicht möglich: Datei oder Verzeichnis nicht gefunden
ls: Zugriff auf '"debug/CYD_1005' nicht möglich: Datei oder Verzeichnis nicht gefunden
ls: Zugriff auf '(Kopie).jpg"' nicht möglich: Datei oder Verzeichnis nicht gefunden
input: "debug/CYD_1005 (Kopie).jpg"
ls -l "debug/CYD_1005 (Kopie).jpg"
ls: Zugriff auf '"debug/CYD_1005' nicht möglich: Datei oder Verzeichnis nicht gefunden
ls: Zugriff auf '(Kopie).jpg"' nicht möglich: Datei oder Verzeichnis nicht gefunden
-rwxr-xr-x 1 ich ich 64855 Mär 26 15:02 'debug/CYD_1005 (Kopie).jpg'
Was muss ich tun, damit die Dateien mit Leerzeichen im Namen richtig verarbeitet werden?
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11176
Wohnort: München
|
Irgendwie habe ich den Eindruck, dass du da auf gut Glück Anführungszeichen escapest - innerhalb von $() kann man die äußersten Anführungszeichen ohne Backslash davor nutzen. Das ist der Vorteil von $() gegenüber der Lösung mit Backticks, dass man Anführungszeichen verschachteln darf. | #!/bin/bash
file="CYD_1005 (Kopie).jpg"
echo file: "${file}"
input="debug/${file}"
echo "input: ${input}"
echo "$(ls -l "${input}")"
ls -l "${input}"
input="debug/${file}"
echo "input: ${input}"
echo "ls -l ${input}"
ls -l "${input}"
|
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3021
Wohnort: Köln
|
Danke für den Tipp! So komme ich der Lösung also näher: | #!/bin/bash
file="CYD_1005 (Kopie).jpg"
echo file: "${file}"
input="debug/${file}"
echo "input: ${input}"
echo "$(ls -l "${input}")"
ls -l "${input}"
|
$ debug/test_spaces.sh
file: CYD_1005 (Kopie).jpg
input: debug/CYD_1005 (Kopie).jpg
-rwxr-xr-x 1 ich ich 64855 Mär 26 15:02 debug/CYD_1005 (Kopie).jpg
-rwxr-xr-x 1 ich ich 64855 Mär 26 15:02 'debug/CYD_1005 (Kopie).jpg'
Jetzt bleibt noch die Frage, wie die Lösung ohne "echo" (letzte Zeile) aussieht, ohne dass im Ergebnis die Hochkommas erscheinen.
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3021
Wohnort: Köln
|
Jetzt komme ich dann mal noch zu meinem eigentlichen Vorhaben ... Die Variable output will ich manuell mittels auskommentieren unterschiedlich setzen, um den Befehl unterschiedlich auszuführen. Setzte ich sie auf -f null - funktioniert folgendes Skript: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | file="CYD_1005 (Kopie).jpg"
echo file: "${file}"
#mode="smear"
mode="mirror"
#mode="fixed:green"
for borders in "0:0:25:25" "25:25:0:0" "25:25:25:25"
do
input="debug/${file}"
# output="\"debug/ZZ_${file%.*}_${mode%:*}-${borders//:/-}.${file##*.}\""
output="-f null -"
echo "output: ${output}"
for build in "./ffmpeg-p0" "./ffmpeg-p7b"
do
# echo "${build} : ${input} --> ${output}"
echo "Befehl: ${build} -y -v error -i \"${input}\" -vf loop=16:1:0:start=0,fillborders=${borders}:${mode} -update 1 ${output}"
${build} -y -v error -i "${input}" -vf loop=16:1:0:start=0,fillborders=${borders}:${mode} -update 1 ${output}
done
done
|
$ debug/test_spaces.sh
file: CYD_1005 (Kopie).jpg
output: -f null -
Befehl: ./ffmpeg-p0 -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=0:0:25:25:mirror -update 1 -f null -
Befehl: ./ffmpeg-p7b -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=0:0:25:25:mirror -update 1 -f null -
217350 decicycles in fillborders=0:0:25:25:mirror 3p-8bit-1x1, 1 runs, 0 skips
242010 decicycles in fillborders=0:0:25:25:mirror 3p-8bit-1x1, 2 runs, 0 skips
247747 decicycles in fillborders=0:0:25:25:mirror 3p-8bit-1x1, 4 runs, 0 skips
262788 decicycles in fillborders=0:0:25:25:mirror 3p-8bit-1x1, 8 runs, 0 skips
251460 decicycles in fillborders=0:0:25:25:mirror 3p-8bit-1x1, 16 runs, 0 skips
output: -f null -
Befehl: ./ffmpeg-p0 -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=25:25:0:0:mirror -update 1 -f null -
Befehl: ./ffmpeg-p7b -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=25:25:0:0:mirror -update 1 -f null -
1932120 decicycles in fillborders=25:25:0:0:mirror 3p-8bit-1x1, 1 runs, 0 skips
1846080 decicycles in fillborders=25:25:0:0:mirror 3p-8bit-1x1, 2 runs, 0 skips
2031682 decicycles in fillborders=25:25:0:0:mirror 3p-8bit-1x1, 4 runs, 0 skips
2146623 decicycles in fillborders=25:25:0:0:mirror 3p-8bit-1x1, 8 runs, 0 skips
1997173 decicycles in fillborders=25:25:0:0:mirror 3p-8bit-1x1, 16 runs, 0 skips
output: -f null -
Befehl: ./ffmpeg-p0 -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=25:25:25:25:mirror -update 1 -f null -
Befehl: ./ffmpeg-p7b -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=25:25:25:25:mirror -update 1 -f null -
1738350 decicycles in fillborders=25:25:25:25:mirror 3p-8bit-1x1, 1 runs, 0 skips
1736820 decicycles in fillborders=25:25:25:25:mirror 3p-8bit-1x1, 2 runs, 0 skips
1823805 decicycles in fillborders=25:25:25:25:mirror 3p-8bit-1x1, 4 runs, 0 skips
1860761 decicycles in fillborders=25:25:25:25:mirror 3p-8bit-1x1, 8 runs, 0 skips
1869283 decicycles in fillborders=25:25:25:25:mirror 3p-8bit-1x1, 16 runs, 0 skips
Setze ich aber | output="\"debug/ZZ_${file%.*}_${mode%:*}-${borders//:/-}.${file##*.}\""
|
bekomme ich wieder das Problem: $ debug/test_spaces.sh
file: CYD_1005 (Kopie).jpg
output: "debug/ZZ_CYD_1005 (Kopie)_mirror-0-0-25-25.jpg"
Befehl: ./ffmpeg-p0 -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=0:0:25:25:mirror -update 1 "debug/ZZ_CYD_1005 (Kopie)_mirror-0-0-25-25.jpg"
[NULL @ 0x5634dcd59b00] Unable to find a suitable output format for '"debug/ZZ_CYD_1005'
"debug/ZZ_CYD_1005: Invalid argument
Befehl: ./ffmpeg-p7b -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=0:0:25:25:mirror -update 1 "debug/ZZ_CYD_1005 (Kopie)_mirror-0-0-25-25.jpg"
[NULL @ 0x55c1d1d70b00] Unable to find a suitable output format for '"debug/ZZ_CYD_1005'
"debug/ZZ_CYD_1005: Invalid argument
output: "debug/ZZ_CYD_1005 (Kopie)_mirror-25-25-0-0.jpg"
Befehl: ./ffmpeg-p0 -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=25:25:0:0:mirror -update 1 "debug/ZZ_CYD_1005 (Kopie)_mirror-25-25-0-0.jpg"
[NULL @ 0x55cb24000b00] Unable to find a suitable output format for '"debug/ZZ_CYD_1005'
"debug/ZZ_CYD_1005: Invalid argument
Befehl: ./ffmpeg-p7b -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=25:25:0:0:mirror -update 1 "debug/ZZ_CYD_1005 (Kopie)_mirror-25-25-0-0.jpg"
[NULL @ 0x563f168e6b00] Unable to find a suitable output format for '"debug/ZZ_CYD_1005'
"debug/ZZ_CYD_1005: Invalid argument
output: "debug/ZZ_CYD_1005 (Kopie)_mirror-25-25-25-25.jpg"
Befehl: ./ffmpeg-p0 -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=25:25:25:25:mirror -update 1 "debug/ZZ_CYD_1005 (Kopie)_mirror-25-25-25-25.jpg"
[NULL @ 0x556c3464db00] Unable to find a suitable output format for '"debug/ZZ_CYD_1005'
"debug/ZZ_CYD_1005: Invalid argument
Befehl: ./ffmpeg-p7b -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=25:25:25:25:mirror -update 1 "debug/ZZ_CYD_1005 (Kopie)_mirror-25-25-25-25.jpg"
[NULL @ 0x5640fd66ab00] Unable to find a suitable output format for '"debug/ZZ_CYD_1005'
"debug/ZZ_CYD_1005: Invalid argument
Welche Lösung könnte es denn dafür geben?
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
seahawk1986 schrieb: Irgendwie habe ich den Eindruck, dass du da auf gut Glück Anführungszeichen escapest - innerhalb von $() kann man die äußersten Anführungszeichen ohne Backslash davor nutzen. Das ist der Vorteil von $() gegenüber der Lösung mit Backticks, dass man Anführungszeichen verschachteln darf.
Nur kommt in dem Script gar keine Command Substitution $(...) vor, sondern Variable Expansion ${}. ☺
| #!/bin/bash
file="CYD_1005 (Kopie).jpg"
echo file: "${file}"
|
Anführungsstriche sind überflüssig. Die variable expansion wird ohne genauso glücken:
, und auch das schlichtere
würde es tun.
input="debug/${file}"
echo "input: ${input}"
Auch hier Gymanastik ohne Wert. Das "debug/" enthält kein Blank oder sonstiges, was der Maskierung bedarf. Das $file erst, nachdem es expandiert wurde, aber dann ist es input schon zugewiesen.
reicht völlig.
| t201:~/proj/mini/forum > input=debug/$file
t201:~/proj/mini/forum > echo $input
debug/CYD_1005 (Kopie).jpg
|
echo "$(ls -l "${input}")"
Was soll das werden? Was soll echo dem Ergebnis hinzufügen, oder soll es was wegmachen? Hier findet erst die Variablenexpansion statt, also ${input} und das Resultat wird ls -l vorgelegt, welches stolpern würde, wenn $input nicht geschützt würde.
| t201:~/proj/mini/forum/arg/heikel > ls -l "$file"
-rw-rw-r-- 1 stefan stefan 14 Mär 28 00:51 hei kel (2019).txt
t201:~/proj/mini/forum/arg/heikel > echo $(ls -l "$file")
-rw-rw-r-- 1 stefan stefan 14 Mär 28 00:51 hei kel (2019).txt
|
Erst wenn man den unnötigen Zinnober weglässt lernt man, was man wann wieso braucht. Hier hält sich aber eine Meinungsclique, die üppiges Auf-Verdacht-Maskierung propagiert. ☺
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11176
Wohnort: München
|
user_unknown schrieb: Nur kommt in dem Script gar keine Command Substitution $(...) vor, sondern Variable Expansion ${}. ☺
Schau mal in Zeile 6: UlfZibis schrieb: bei der Ausführung des folgenden Skripts unter debug/test_spaces.sh 1
2
3
4
5
6
7
8
9
10
11
12
13 | #!/bin/bash
file="CYD_1005 (Kopie).jpg"
echo file: "${file}"
input="debug/${file}"
echo "input: ${input}"
echo "$(ls -l \"${input}\")"
ls -l \"${input}\"
input="\"debug/${file}\""
echo "input: ${input}"
echo "ls -l ${input}"
ls -l ${input}
# Kontrolle:
ls -l "debug/CYD_1005 (Kopie).jpg"
|
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11176
Wohnort: München
|
UlfZibis schrieb: Welche Lösung könnte es denn dafür geben?
Variablen dann quoten, wenn man auf ihren Wert zugreifen will, statt vorab in Strings unnötige Anführungszeichen einzubauen und Argumente mit variabler Länge in einen Array packen statt in einen String, der später wieder am IFS aufgetrennt werden muss (ein String wie er der auskommentierten Variable output in Zeile 7 zugewiesen wird, ist immer das Element an Position 0, wenn man auf die Variable als Array zugreift):
1
2
3
4
5
6
7
8
9
10
11
12
13 | #!/bin/bash
file="CYD_1005 (Kopie).jpg"
mode="mirror"
for borders in "0:0:25:25" "25:25:0:0" "25:25:25:25"
do
input="debug/${file}"
# output="debug/ZZ_${file%.*}_${mode%:*}-${borders//:/-}.${file##*.}"
output=('-f' 'null' '-')
for build in "./ffmpeg-p0" "./ffmpeg-p7b"
do
"${build}" -y -v error -i "${input}" -vf "loop=16:1:0:start=0,fillborders=${borders}:${mode}" -update 1 "${output[@]}"
done
done
|
Statt der ganzen echo-Befehle kann es oft praktischer sein die anderen in https://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html beschriebenen Methoden zum Debugging zu nutzen.
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3021
Wohnort: Köln
|
Moin moin, Ihr wart ja fleißig und seid durch mein kompliziertes Skript schon durchgestieben, danke! Mir fiel nämlich heute Nacht noch eine einfacher nachvollziehbare Variante ein ... siehe unten. user_unknown schrieb: Erst wenn man den unnötigen Zinnober weglässt lernt man, was man wann wieso braucht. Hier hält sich aber eine Meinungsclique, die üppiges Auf-Verdacht-Maskierung propagiert. ☺
Da muss ich Dir zustimmen, auch ich liebe eher den Minimalismus. Ich wollte halt auf Nummer sicher gehen ... und oft ist es dann beim Sparen von Anführungszeichen auch so, dass sich erst später ein Problem zeigt. Ursprünglich hatte ich nämlich nur Dateinamen ohne Leerzeichen, was sich in meinem komplizierten Skript dann später rächte. Daher rühren all meine Fragen. Im einfachen Beispiel ging's mir nur um die letzte Zeile. Warum tauchen da auf einmal Hochkommas in der Ausgabe auf, bzw. wie kann ich die verhindern? | file="CYD_1005 (Kopie).jpg"
echo file: $file
input=debug/$file
echo input: $input
echo $(ls -l "$input")
ls -l "$input"
|
$ debug/test_spaces.sh
file: CYD_1005 (Kopie).jpg
input: debug/CYD_1005 (Kopie).jpg
-rwxr-xr-x 1 ich ich 64855 Mär 26 15:02 debug/CYD_1005 (Kopie).jpg
-rwxr-xr-x 1 ich ich 64855 Mär 26 15:02 'debug/CYD_1005 (Kopie).jpg' seahawk1986 schrieb: statt vorab in Strings unnötige Anführungszeichen einzubauen und Argumente mit variabler Länge in einen Array packen statt in einen String, der später wieder am IFS aufgetrennt werden muss (ein String wie er der auskommentierten Variable output in Zeile 7 zugewiesen wird, ist immer das Element an Position 0, wenn man auf die Variable als Array zugreift):
Hey genial, das funktioniert. Möglichst minimalistisch sieht es dann wohl so aus: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | #!/bin/bash
file="CYD_1005 (Kopie).jpg"
mode="mirror"
for borders in "0:0:25:25" "25:25:0:0" "25:25:25:25"
do
input=debug/$file
# output=debug/ZZ_${file%.*}_${mode%:*}-${borders//:/-}.${file##*.}
output=('-f' 'null' '-')
for build in "ffmpeg" # "./ffmpeg-p7b"
do
echo "$build : $input --> ${output[@]}"
echo "$build -y -v error -i \"$input\" -vf loop=16:1:0:start=0,fillborders=$borders:$mode -update 1 \"${output[@]}\""
$build -y -v error -i "$input" -vf loop=16:1:0:start=0,fillborders=$borders:$mode -update 1 "${output[@]}"
done
done
|
So richtig kapieren tue ich ja nicht, warum das so funktioniert, denn schreibe ich das Ergebnis von Zeile 12 manuell ins Terminal, bekomme ich wieder den Fehler: $ ffmpeg -y -v error -i "debug/CYD_1005 (Kopie).jpg" -vf loop=16:1:0:start=0,fillborders=25:25:25:25:mirror -update 1 "-f null -"
Unrecognized option 'f null -'.
Error splitting the argument list: Option not found Warum hast Du denn ${build} und das Argument von -vf gequotet?
Statt der ganzen echo-Befehle kann es oft praktischer sein die anderen in https://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html beschriebenen Methoden zum Debugging zu nutzen.
Gucke ich mir mal an, danke!
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11176
Wohnort: München
|
UlfZibis schrieb: $ debug/test_spaces.sh
file: CYD_1005 (Kopie).jpg
input: debug/CYD_1005 (Kopie).jpg
-rwxr-xr-x 1 ich ich 64855 Mär 26 15:02 debug/CYD_1005 (Kopie).jpg
-rwxr-xr-x 1 ich ich 64855 Mär 26 15:02 'debug/CYD_1005 (Kopie).jpg'
Jetzt bleibt noch die Frage, wie die Lösung ohne "echo" (letzte Zeile) aussieht, ohne dass im Ergebnis die Hochkommas erscheinen.
Das automatische Einfügen von einfachen Hochkommas wenn Dateinamen mit Zeichen auftauchen, die ansonsten escaped werden müssten, ist ein Feature von neueren Versionen von ls (dessen Ausgabe man normalerweise niemals nicht in einem Skript weiterverarbeiten sollte).
Wie in https://www.gnu.org/software/coreutils/manual/html_node/Formatting-the-file-names.html beschrieben kannst du das gezielt mit -N unterdrücken, also sowas schreiben:
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3021
Wohnort: Köln
|
UlfZibis schrieb: Hier noch mal ein PING. Durch das gleichzeitige Abschicken unserer beiden letzten Beiträge hast Du wohl keine E-Mail-Benachrichtigung über meinen letzten Post bekommen. seahawk1986 schrieb: Wie in https://www.gnu.org/software/coreutils/manual/html_node/Formatting-the-file-names.html beschrieben kannst du das gezielt mit -N unterdrücken, also sowas schreiben:
Auch genial, danke!
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11176
Wohnort: München
|
UlfZibis schrieb: Warum hast Du denn ${build} und das Argument von -vf gequotet?
Weil theoretisch durch die Variablen-Expansion Zeichen auftauchen können, die von der Shell am IFS aufgesplittet werden (z.B. wenn dein ffmpeg als absoluter oder relativer Pfad angegeben wird und Ordnernamen in diesem Pfad Leerzeichen enthalten). Somit nagelt man die Zahl der Argumente auf die erwartete Anzahl fest.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
seahawk1986 schrieb: user_unknown schrieb: Nur kommt in dem Script gar keine Command Substitution $(...) vor, sondern Variable Expansion ${}. ☺
Schau mal in Zeile 6:
Da hast Du absolut Recht. UlfZibis schrieb:
Möglichst minimalistisch sieht es dann wohl so aus:
Lange nicht! ☺
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | #!/bin/bash
file="CYD_1005 (Kopie).jpg"
# Stings im Sinne von Zeichenketten bedürfen in der Bash nicht generell der Maskierung. Syntaxhighlighting im Editor unterstützt die Konfusion.
# mode="mirror"
mode=mirror
# Auch hier nicht:
# for borders in "0:0:25:25" "25:25:0:0" "25:25:25:25"
for borders in 0:0:25:25 25:25:0:0 25:25:25:25
do
input=debug/$file
output=('-f' 'null' '-')
# wieder nicht:
for build in ffmpeg # ./ffmpeg-p7b
do
echo "$build : $input --> ${output[@]}"
echo "$build -y -v error -i \"$input\" -vf loop=16:1:0:start=0,fillborders=$borders:$mode -update 1 \"${output[@]}\""
$build -y -v error -i "$input" -vf loop=16:1:0:start=0,fillborders=$borders:$mode -update 1 "${output[@]}"
done
done
|
Die wichtigen Korrekturen der anderen sind hier aber nicht übernommen (output=('-f' 'null' '-')).
|
UlfZibis
(Themenstarter)
Anmeldungsdatum: 13. Juli 2011
Beiträge: 3021
Wohnort: Köln
|
user_unknown schrieb: UlfZibis schrieb: Möglichst minimalistisch sieht es dann wohl so aus:
Lange nicht! ☺
| # Stings im Sinne von Zeichenketten bedürfen in der Bash nicht generell der Maskierung. Syntaxhighlighting im Editor unterstützt die Konfusion.
[.....]
|
Sehr cool. 😎 Die wichtigen Korrekturen der anderen sind hier aber nicht übernommen (output=('-f' 'null' '-')).
Öhm, sind doch übernommen ???
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
Öhm, ja. Schwach ausgedrückt. Um die korrekte Übernahme aller Korrekturen habe ich mich nicht weiter gekümmert - so war's gemeint.
|