Verwenden Sie das mktemp
Dienstprogramm, um eine temporäre Datei mit einem unvorhersehbaren Namen zu erstellen. Es ist nicht von POSIX standardisiert, aber sowohl auf * BSD als auch auf Linux verfügbar.
> /tmp/predictable.$RANDOM
Dies ist keine gute Wahl, da es meistens vorhersehbar ist¹, wodurch Ihr Skript für einen Angriff geöffnet wird, bei dem der Angreifer Ihr Skript dazu verleiten kann, eine Datei zu überschreiben, auf die Sie Schreibzugriff haben, oder ihnen Zugriff auf die temporäre Datei zu gewähren. Dies ist eine unsichere Sicherheitsanfälligkeit für temporäre Dateien . mktemp
hat diese Sicherheitsanfälligkeit nicht, da die Datei sicher erstellt wird (es wird keine vorhandene Datei überschrieben, auch wenn symbolische Links vorhanden sind) und ein ausreichend unvorhersehbarer Name verwendet wird, um einen Denial-of-Service zu vermeiden.
Wenn es nicht gut genug ist, eine temporäre Datei zu erstellen und damit zu arbeiten, erstellen Sie ein temporäres Verzeichnis mit mktemp -d
und arbeiten Sie dort.
mktemp
Es wird auch darauf geachtet, $TMPDIR
wenn die Variable gesetzt ist, und auf zurückzugreifen, /tmp
wenn sie nicht gesetzt ist.
Immer mehr Distributionen TMPDIR
werden als privates Verzeichnis eingerichtet, z. B. /run/1234/tmp
wo 1234
ist Ihre UID. Hierdurch wird das Risiko von Sicherheitslücken in Bezug auf temporäre Dateien beseitigt, da temporäre Dateien nicht mehr zwischen Benutzern ausgetauscht werden können (was gelegentlich nützlich ist, aber nicht sehr häufig; /tmp
ist immer noch verfügbar, nur nicht TMPDIR
).
Wenn Sie einen reproduzierbaren Dateinamen benötigen, erstellen Sie eine Datei mit einem genau definierten Namen (ohne zufällige Komponente) im Basisverzeichnis des Benutzers. Die moderne Konvention ist die XDG-Benutzerverzeichnisspezifikation . Wenn die Datei ohne Datenverlust entfernt werden konnte, verwenden Sie die XDG_CACHE_HOME
Umgebungsvariable mit dem Standardwert "" ~/.cache
. Sie sollten wahrscheinlich ein nach Ihrer Anwendung benanntes Unterverzeichnis erstellen und dort arbeiten.
CACHE_DIR="${XDG_CACHE_HOME:-"$HOME/.cache"}"/Wildcard-scripts
[ -d "$CACHE_DIR" ] || mkdir -p -- "$CACHE_DIR"
CACHE_FILE="$CACHE_DIR/tmpfileformyscript"
¹ Nimmt nicht $RANDOM
nur 32767 mögliche Werte an, sondern ist auch leicht vorherzusagen, ohne viele Werte auszuprobieren. Der Zufallszahlengenerator von Bash ist eine LCG , die nach PID und Zeitpunkt der ersten Verwendung geimpft wird. Zsh ist der Startzeitpunkt der Plattform rand
. ATT Ksh's ist die Plattform, die rand
von PID geimpft wird. Mkshs ist eine LCG mit einem komplexeren, aber immer noch nicht sicherheitsrelevanten Saatgut. Alle von ihnen können durch einen anderen Prozess mit einer ziemlich großen Erfolgschance vorhergesagt werden.
$TMPDIR
und~/.cache
genau das, was ich brauchte. Nach einigen weiteren Überlegungen wurde mir klar, dass der einzige Grund, warum ich es wollte,/tmp
die Partitionierung war - also konnte der Cache die/home
Partition nicht füllen . Aber für diesen Anwendungsfall ist das wirklich kein Problem, sodass ein Unterverzeichnis~/.cache
meiner Anforderungen perfekt entspricht und die Sicherheitslücke schließt.mktemp
ist unter AIX oder der Git-Shell unter Windows nicht verfügbar. Es sieht aus wiefile.$RANDOM$RANDOM
ist die portable Lösung. Der$RANDOM$RANDOM
Speicherplatz sollte auf 2 ^ 32 erhöht werden, vorausgesetzt, die zufälligen Bash-Ergebnisse sind unabhängig und nicht schwach.Dafür wurde mktemp entwickelt. Von der Manpage:
mktemp erstellt die Datei oder beendet sie mit einem Exit-Status ungleich Null. Das logische oder (||) stellt sicher, dass das Skript beendet wird, wenn mktemp die Datei nicht erstellen kann. Nach diesem Befehl können Sie sicher sein, dass die Datei verfügbar ist. Es besteht keine Notwendigkeit, es erneut zu überprüfen. Das einzige, was Sie möglicherweise hinzufügen müssen, ist die Bereinigung der Datei am Ende Ihres Skripts.
Und möglicherweise auch, wenn das Skript durch ein Signal beendet wird. Ob das notwendig ist oder nicht, müssen Sie entscheiden.
Beides kann mit dem
trap
Befehl erfolgen.quelle
$RANDOM
. Aber dann Teil 2 meiner Frage: Wie kann ich später auf diese Datei zugreifen oder prüfen, ob sie bei einer nachfolgenden Ausführung des Skripts bereits vorhanden ist? (Um einen sehr einfachen Cache zu implementieren.)