Ich habe ein Skript geschrieben, das alle außer den letzten beiden Dateien in einem Ordner löscht:
#!/bin/bash
ls -1 --quoting-style=shell-always /path/to/some/folder \
| head -n -2 \
| xargs printf -- "'/path/to/some/folder/%s'\n" \
| xargs sudo rm -rf
Dieses Skript wird jeden Tag als Cron-Job ausgeführt.
Die Argumentation ist wie folgt:
Erhalten Sie eine Liste aller Dateien mit
ls -1
(so dass ich eine Datei pro Zeile bekomme);Entfernen Sie die letzten beiden aus der Liste mit
head -n -2
;Da
ls
relative Pfade gedruckt werden,xargs printf
stellen Sie dem Ordnerpfad das Element voran und machen Sie ihn zu einem absoluten Pfad.Senden Sie sie an
sudo rm -rf
usingxargs
.
Jeder hat Zugriff auf diesen Ordner, sodass jeder alle Dateien in diesem Ordner erstellen und löschen kann.
Das Problem ist: sudo rm -rf
ist beängstigend. xargs sudo rm -rf
ist unglaublich beängstigend.
Ich möchte sichergehen, dass niemand andere Ordner / Systeme beschädigen kann, indem er clevere Dateien erstellt, die (versehentlich oder absichtlich) gelöscht werden sollen. Ich weiß nicht, etwas Kluges wie:
file with / spaces.txt
was zu einer super beängstigend führen könnte sudo rm -rf /
.
EDIT: Mein Fehler, Dateinamen können nicht enthalten /
, so dass dieses spezielle Problem nicht auftreten würde, aber die Frage, ob es andere Risiken gibt oder nicht, bleibt bestehen.
Aus diesem Grund verwende ich --quoting-style=shell-always
, dies sollte Tricks mit Dateien mit Leerzeichen verhindern. Aber jetzt frage ich mich, ob jemand mit Leerzeichen und Anführungszeichen im Dateinamen vielleicht besonders klug sein könnte .
Ist mein Skript sicher?
Hinweis: Ich brauche, sudo
weil ich auf den Ordner remote zugreife (von einem zugeordneten Netzwerklaufwerk mit mount
) und ich ihn ohne sudo nicht zum Laufen bringen könnte.
printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
?/
im Namen erstellt werdenls
Ausgabe analysieren, ist dies selbst beim Zitieren bereits ein schlecht geschriebener Befehl.ls
Ich denke, es wird auch das Gebietsschema zum Sortieren der Reihenfolge verwendet, sodass ich nicht sehe, wozu diehead
letzten 2 entfernt werden sollen (es sei denn, Sie versuchen, sie zu entfernen,.
und..
welche iirc sindrm
sowieso nicht als Argumente zulässig . Verwenden Sie sie einfachfind /path/to/folder -type f delete
. Und Nein,sudo
wenn Sie von Cron laufen - Cron ist bereits auf Root-EbeneAntworten:
Unter Linux ist jedes Zeichen ein gültiger Dateiname, der ein Zeichen darstellt, mit Ausnahme von:
\0
(ASCII NUL): wie für die Zeichenfolgenbeendigung in C verwendet/
(Schrägstrich): wie für die Pfadtrennung verwendetIhr Ansatz wird also in vielen Fällen definitiv nicht funktionieren, wie Sie sich vorstellen können, z. B. behandelt er eine neue Zeile (
\n
) im Dateinamen? ( Hinweis: Nein ).Einige Anmerkungen:
ls
; Verwenden Sie spezielle Tools (für die meisten Anwendungsfälle gibt es mindestens eines).xargs
, prüfen Sie , ob Sie damit durchkommen könnenfind ... -exec
. In den meisten Fällen geht es Ihnen gut, wenn Siefind
alleine sindIch denke, das wird dich jetzt zum Laufen bringen. steeldriver hat die NUL-getrennte Idee bereits im Kommentar (
printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm
) angegeben. Verwenden Sie diese als Ausgangspunkt.quelle
find
, danke für den Vorschlag.ls
, in welchen zahlreichen Fällen dein Parsing-Ansatz fehlschlagen würde, z. B. hast du eine neue Zeile im Dateinamen berücksichtigt?head -z
das? Es klingt lächerlich, aber ich habeman
nochinfo
in meinem CoreOS-Container Linux ... Konnte auch nicht im Internet finden. Ich bekommehead: invalid option 'z'
head
(wird mit GNU geliefertcoreutils
). Hier ist die Online - Version: manpages.ubuntu.com/manpages/xenial/man1/head.1.htmlxargs
unterstützt einige Anführungszeichen: mit einfachen Anführungszeichen, doppelten Anführungszeichen oder Backslash, wodurch beliebige Argumente akzeptiert werden¹, jedoch mit einer Syntax, die sich von der Anführungszeichen-Syntax der Bourne-ähnlichen Shells unterscheidet.Die GNU-Implementierung von
ls
Ubuntu verfügt über keinen Anführungsmodus, der mit demxargs
Eingabeformat kompatibel ist .Es
ls --quoting-style=shell-always
ist kompatibel mit ksh93-, bash- und zsh-Shells, die die Syntax angeben, jedoch nur, wenn die Ausgabe vonls
von der Shell im selben Gebietsschema interpretiert wird, in demls
sie ausgegeben wurde. Außerdem sollten einige Gebietsschemas, z. B. BIG5, BIG5-HKSCS, GBK oder GB18030, vermieden werden.Mit diesen Muscheln können Sie also tatsächlich Folgendes tun:
Aber das hat wenig Vorteil gegenüber:
Der einzige Fall, in dem es nützlich wird, ist, wenn Sie die
-t
Option verwenden möchten,ls
die Dateien nach mtime / atime / ctime oder-S
/ zu sortieren-V
. Aber selbst dann können Sie genauso gutzsh
Folgendes verwenden:Zum Beispiel, um die Dateien nach mtime zu sortieren (verwenden Sie
oL
für-S
undn
für-V
).So entfernen Sie alle bis auf die beiden zuletzt geänderten regulären Dateien:
¹ Es gibt immer noch einige Längenbeschränkungen (durch
execve()
und in einigen Nicht-GNU-xargs
Implementierungen viel niedrigere willkürliche), und einige Nicht-GNU-xargs
Implementierungen drosseln die Eingabe, die Sequenzen von Bytes enthält, die keine gültigen Zeichen bilden.quelle