Eine Shell-Zuweisung ist ein einzelnes Wort ohne Leerzeichen nach dem Gleichheitszeichen. Was Sie geschrieben haben, weist also einen leeren Wert zu thefile
. Da die Zuweisung mit einem Befehl gruppiert ist, wird thefile
eine Umgebungsvariable erstellt, und die Zuweisung ist für diesen bestimmten Befehl lokal, dh nur für den Aufruf, ls
der den zugewiesenen Wert sieht.
Sie möchten die Ausgabe eines Befehls erfassen, daher müssen Sie die Befehlsersetzung verwenden :
thefile=$(ls -t -U | grep -m 1 "Screen Shot")
(Einige Literaturstellen zeigen eine alternative Syntax thefile=`ls …`
; die Backquote-Syntax entspricht der Syntax in Dollar-Klammern, mit der Ausnahme, dass das Zitieren in Backquotes manchmal seltsam ist. Verwenden Sie einfach $(…)
.)
Weitere Anmerkungen zu Ihrem Skript:
- Das Kombinieren
-t
(nach Zeit sortieren) mit -U
(nicht sortieren) ergibt keinen Sinn. benutze einfach -t
.
Anstatt grep
Screenshots abzugleichen, ist es einfacher, einen Platzhalter zu übergeben ls
und head
die erste Datei zu erfassen:
thefile=$(ls -t *"Screen Shot"* | head -n 1)
Es ist im Allgemeinen eine schlechte Idee, die Ausgabe von zu analysierenls
. Dies kann sehr schlimm sein, wenn Sie Dateinamen mit nicht druckbaren Zeichen haben. Das Sortieren von Dateien nach Datum ist jedoch schwierig ls
, und daher ist es eine akzeptable Lösung, wenn Sie wissen, dass Dateinamen keine nicht druckbaren Zeichen oder umgekehrten Schrägstriche enthalten.
Verwenden Sie immer doppelte Anführungszeichen um variable Substitutionen , dh schreiben Sie hier
echo "Most recent screenshot is: $thefile"
Ohne doppelte Anführungszeichen wird der Wert der Variablen erneut erweitert, was zu Problemen führt, wenn Leerzeichen oder andere Sonderzeichen enthalten sind.
- Sie brauchen keine Semikolons am Ende einer Zeile. Sie sind überflüssig, aber harmlos.
- In ein Shell-Skript ist es oft eine gute Idee, es einzuschließen
set -e
. Dies weist die Shell an, zu beenden, wenn ein Befehl fehlschlägt (indem ein Nicht-Null-Status zurückgegeben wird).
Wenn Sie GNU find verwenden (insbesondere wenn Sie nicht-eingebettetes Linux oder Cygwin verwenden), gibt es einen anderen Ansatz, um die neueste Datei zu finden: Sie müssen find
die Dateien und ihre Daten auflisten sort
und tail
die jüngste Datei mit und extrahieren.
thefile=$(find -maxdepth 1 -type f -name "*Screen Shot*" -printf "%T@ %p" |
sort -k 1n | tail -n 1)
Wenn Sie bereit sind, dieses Skript in zsh anstatt in bash zu schreiben, können Sie die neueste Datei auf viel einfachere Weise abrufen, da zsh Glob-Qualifikationsmerkmale enthält , die Platzhalter-Übereinstimmungen nicht nur für Namen, sondern auch für Dateimetadaten ermöglichen. Der (om[1])
Teil nach dem Muster ist das Glob-Qualifikationsmerkmal. om
sortiert Übereinstimmungen nach zunehmendem Alter (dh nach Änderungszeit, neueste zuerst) und [1]
extrahiert nur die erste Übereinstimmung. Die gesamte Übereinstimmung muss in Klammern angegeben werden, da es sich technisch gesehen um ein Array handelt, da beim Verschieben eine Liste von Dateien zurückgegeben wird, auch wenn [1]
dies in diesem speziellen Fall bedeutet, dass die Liste (höchstens) eine Datei enthält.
#!/bin/zsh
set -e
cd ~/Desktop
thefile=(*"Screen Shot"*(om[1]))
echo "Most recent screenshot is: $thefile"