Verwenden Sie keine Befehlsersetzung für die Ausgabe vonfind
. Hier kann alles gemacht werden mit find
:
find . -mtime 1 -type f ! -exec lsof -t {} \; -exec rm -f {} \; > /dev/null
Mit ein paar find
Implementierungen (einschließlich FreeBSD, find
woher es kommt, und GNU find
) können Sie -delete
anstelle von verwenden -exec rm...
.
Der Grund, warum Sie eine Fehlermeldung erhalten, besteht darin, dass zwischen then
und else
und einigen Shells (beginnend mit der Bourne-Shell, von der diese Syntax stammt) kein Befehl vorhanden ist (und ein Kommentar kein Befehl ist). Beachten Sie, dass dies völlig willkürlich ist und es keinen Grund gibt, warum diese Shells dies tun würden. yash
und zsh
haben diese Einschränkung nicht ( if false; then else echo x; fi
und if false; then else fi
funktionieren sogar gut mit ihnen).
Wie andere gesagt haben, können Sie einen noop-Befehl wie :
(oder for nothing in; do nothing; done
) verwenden oder die Logik mit dem !
Schlüsselwort umkehren (verfügbar in POSIX-Shells, aber nicht in der Bourne-Shell (Sie werden feststellen, :
dass dies in dieser Shell üblich war)). mksh
und yash
zufällig unterstützen if false; then () else echo x; fi
(ich würde mich nicht darauf verlassen, da sich dies in zukünftigen Versionen ändern könnte).
Ein anderer Ansatz ist mit:
lsof... || {
cmd1
cmd2
}
Ein Unterschied ist jedoch der Gesamt-Exit-Status, der dem entspricht, lsof
wenn ein lsof
Fehler auftritt.
-exec
oft nützlich istxargs
, wird manchmal eine Shell-Schleife benötigt. In diesem Fall ist einewhile read name
Schleife die bevorzugte Option (in bash mit GNU find können Sie die Option -0 für beide verwenden; möglicherweise müssen Sie auf newline verzichten).-print0
ist-exec printf '%s\0' {} +
(aber portabel können Sie mit dieser Ausgabe nicht umgehen, außer wenn Sie dies berücksichtigen möchtenperl
), und mitfind .//.
und etwas Nachbearbeitung können Sie den Zeilenumbrüchen für entkommenxargs
. Beachten Sie, dass es kein istwhile read
, es istwhile IFS= read -r
.Es scheint, dass Sie ein No-Op ausführen möchten, wenn die Datei geöffnet ist. Fügen Sie
:
daher einen Null-Befehl hinzubash
:Wenn Sie nicht verwenden
:
,bash
können Sie den Code nicht analysieren und es wird ein Fehler wie angezeigtbash: syntax error near unexpected token 'else'
.quelle
:
und es ist der erste Befehl, der in bash-builtins aufgeführt wird.Eine andere Alternative: kehren Sie Ihre Logik um.
quelle
TL; DR
Keine der anderen Antworten beantwortet tatsächlich Ihre ursprüngliche Frage, warum der Befehl einen Syntaxfehler ausgibt. Dies wird durch einen fehlenden Befehl zwischen then und else verursacht .
Ein fehlender Befehl
Ihr ursprünglicher Code sieht folgendermaßen aus:
Das Problem ist, dass Sie zwischen then und else einen Kommentar haben , dieser jedoch nicht als Befehl behandelt wird. Kurz gesagt, Sie könnten das Problem (strukturell gesehen) wie folgt umschreiben:
Korrigieren Sie Ihre Syntax mit einem Bourne Builtin
Sie können dieses Problem beheben, indem Sie die tatsächlichen Befehle vor andere Befehle stellen. Ein Kommentar allein reicht jedoch nicht aus. Der If-Then- Abschnitt darf nicht leer sein. Wenn Sie einen Platzhalter möchten, können Sie den eingebauten Doppelpunkt verwenden . Beispielsweise:
Durch einfaches Einfügen
:
in den Abschnitt zwischen then und else wird der aufgetretene Syntaxfehler behoben.quelle
$ ; -bash: syntax error near unexpected token ';'