Wie erstelle ich eine temporäre Datei im RAM?

29

Ich habe ein Skript, an das die Ausgabe weitergeleitet wird |tee scriptnameYYMMDD.txt. Nach jedem Zyklus der for-Schleife, in der die Ausgabe generiert wird, kehre ich den Dateiinhalt um, tac scriptnameYYYYMMDD.txt > /var/www/html/logs/scriptname.txtsodass die Protokollausgabe in einem Browserfenster mit den neuesten Zeilen oben sichtbar ist.

Ich werde mehrere Skripte gleichzeitig ausführen lassen. Ich versuche, die Festplattenaktivität zu minimieren, daher ist die Ausgabe von |tee scriptnameYYYYMMDD.txtauf eine RAM-Disk am besten. mktempErstellt eine Datei im /tmpOrdner, die jedoch nicht offline zu sein scheint.

user208145
quelle
Es muss ein RAMFS oder ein TMPFS sein (Sekunde ist besser). Überprüfen Sie, ob ein solches fs bereits auf Ihrem System installiert ist, wenn ja, können Sie das verwenden. Wenn nein, müssen Sie es mounten.
Peter sagt, Monica
Ich würde aktualisieren , fstabum eine Montage tmpfsauf /tmpund dann den Rechner neu starten.
Kasperd
1
Sie könnten in Betracht ziehen, taildie Dateien inkrementell zu erstellen (oder sie auf Anfrage oder so etwas über CGI zu starten), anstatt tacdas Ganze zu erstellen.
mikeserv
Dies scheint beim Testen zu funktionieren (Entschuldigung für die verringerte Formatierung): TEMPPATH="/ramdisk" LOGPATH="/var/www/html/log" ... echo <various calls to echo> | tee -a $TEMPPATH/moveKRT$(date '+%Y%m%d').txt ... am Ende der for-Schleife bin cp $TEMPPATH/moveKRT$(date '+%Y%m%d').txt $LOGPATH/moveKRT$(date '+%Y%m%d').txt tac $TEMPPATH/moveKRT$(date '+%Y%m%d').txt > $LOGPATH/moveKRT.txt ich mir der winzigen Möglichkeit bewusst, dass der Wechsel von 23: 59: 59.999 auf 00:00: 00 kann sich auf einige Dateien auswirken, aber die Chance ist akzeptabel.
user208145
Update über meine Fortschritte in diesem Bereich: Ich habe ein 1 GB tmpfs-Volume unter / ramdisk gemountet. Ich habe Dateien, die über FTP in Benutzerordner gelangen. Sie werden zum Verarbeiten in einen Unterordner / ramdisk / quees / xyz / verschoben und anschließend gelöscht. Beim Start habe ich ein Skript, das meine benötigte Verzeichnisstruktur unter / ramdisk neu erstellt. Dies sollte zu einer minimalen Festplattenaktivität für die eingehenden Dateien führen. Die einzige andere Möglichkeit, die Festplatten-E / A für diese Skripts zu reduzieren, besteht darin, diese Benutzerordner in einem beim Start erstellten tmpfs zu erstellen, bevor Dateien über FTP in diese Benutzerordner gelangen. Vielen Dank an alle.
user208145

Antworten:

22

Sie können eine tmpfsPartition mounten und die Datei dort schreiben:

mount -t tmpfs -o size=500m tmpfs /mountpoint

Diese Partition ist jetzt auf 500 MB beschränkt. Wenn Ihre temporäre Datei größer als 500 MB wächst tritt ein Fehler auf: no space left on device. Es spielt jedoch keine Rolle, wenn Sie mehr Speicherplatz angeben, als der Arbeitsspeicher Ihres Systems hat. tmpfsVerwendet auch Swap Space, sodass Sie im Gegensatz zu keinen Systemabsturz erzwingen können ramfs.

Sie können jetzt Ihre Datei schreiben in /mountpoint:

command | tee /mountpoint/scriptnameYYYYMMDD.txt
Chaos
quelle
3
size=[num]%ist auch in Ordnung - ein tmpfs kann auf einen Prozentsatz des verfügbaren Speichers begrenzt werden. Dies ist normalerweise einfacher, wenn die Befehle nicht immer auf dieselbe (reale / virtuelle) Maschine abzielen. Praktisch ist auch, dass ein tmpfs keine Inhalte mit fallen lässt -o remount,size=newsize.
mikeserv
1
Da es sich bei der Frage um ein Bash-Skript handelt, von dem wir keinen Grund zur Annahme haben, dass es von root ausgeführt wird, können Sie angeben, ob mountBenutzer ohne Rootberechtigung das Skript nicht verwenden dürfen -toder nicht -o. Das heißt, wie kann man Skripte erstellen, die tmpfs(oder auf andere Weise) RAM zum Speichern von Festplattenoperationen verwenden, wenn auf dem System noch kein geeignetes Dateisystem vorhanden ist?
Jonathan Y.
Keine gute Antwort. Scheitert, wenn Sie nicht root sind.
Alex
11

Versuchen Sie dies mit Ubuntu:

ramtmp="$(mktemp -p /dev/shm/)"
tac scriptnameYYYYMMDD.txt > "$ramtmp"
Cyrus
quelle
3
Wie stabil ist das Schreiben /run/shm/? Kann ich chmodbei Bedarf Änderungen an der temporären Datei vornehmen? Ich habe festgestellt, dass die Modusbits des Ordners mit denen des Ordners identisch sind /tmp. Vielen Dank.
user208145
1
Wie bei anderen Verzeichnissen haben auch in /run/shm(symlink to /dev/shm) erzeugte Dateien mktempeine Standardberechtigung von -rw-------(600) und können bei Bedarf mit geändert werden sudo chmod.
KrisWebDev
9

Die folgende Antwort wurde durch Untersuchen der vorherigen Antworten und der Informationen in dieser Frage hier entdeckt und wäre ohne sie nicht gefunden worden. Ein dickes Lob an sie.

Auf meinem LinuxMint-System (und ich würde davon ausgehen, dass die meisten Ubuntu-basierten Systeme und möglicherweise auch Debian-basierte Systeme) ist ein benutzereigener tmpfs installiert, der automatisch darauf installiert wird /run/user/1000/

Verwenden Sie df -Tzu überprüfen.

11:41:11 jesse @ limbo: ~ $ df -T
Dateisystemtyp 1K-Blöcke Verwendet Verfügbar Verwendung% Eingehängt an
udev devtmpfs 15904812 4 15904808 1% / dev
tmpfs tmpfs 3184120 1700 3182420 1% / Durchlauf
/ dev / sdb2 ext4 14248880 11464788 2037240 85% /
keine tmpfs 4 0 4 0% / sys / fs / cgroup
keine tmpfs 5120 0 5120 0% / run / lock
keine tmpfs 15920584 848 15919736 1% / run / shm
keine tmpfs 102400 12 102388 1% / run / user
/ dev / sdb3 ext4 100861352 90755700 4959136 95% / mnt / data

Darunter /run/user/befindet sich ein Verzeichnis für jeden normalen Benutzer im System

12:07:35 jesse@Limbo:~$ ls -l /run/user
total 0
drwx------ 2 root  root   40 Aug  7 09:50 0
drwx------ 8 jesse jesse 180 Aug  7 11:38 1000

Diese Verzeichnisse sind nach den IDs ihrer jeweiligen Benutzer benannt. Wir können die Benutzer - ID mit bekommen id -usiehe man idfür weitere Einzelheiten zu diesem Befehl.

12:07:43 jesse@Limbo:~$ ls -l /run/user/$(id -u)
total 0
drwx------ 2 jesse jesse  60 Aug  7 09:50 dconf
dr-x------ 2 jesse jesse   0 Aug  7 09:50 gvfs
drwx------ 2 jesse jesse  80 Aug  7 09:50 pulse
lrwxrwxrwx 1 root  root   17 Aug  7 09:50 X11-display -> /tmp/.X11-unix/X0

Wir können dann den mktempBefehl mit der --tmpdirOption verwenden, um temporäre Dateien und Verzeichnisse in diesem tempfilesystem zu erstellen und so tempfiles im RAM zu erstellen.

Gemäß den hier gegebenen Hinweisen erstelle ich ein temporäres Verzeichnis und erstelle dann meine temporären Dateien darin:

mydir=$(mktemp -dt "$(basename $0).XXXXXXXX" --tmpdir=/run/user/$(id -u))

erstellen ein temporäres Verzeichnis /run/user/1000/bash.w42BYxbG/dann

myfile=$(mktemp -t "$(basename $0).XXXXXXXX" --tmpdir=$mydir)

darin ein tempfile erstellen.

Das macht das Aufräumen dieser Datei einfach, da ich nur noch tun muss rm -r $mydir.

Standardmäßig gehören alle diese Dateien und können nur von dem Benutzer gelesen werden, der sie erstellt hat.

Anmerkung: Der $(basename $0)Teil des Befehls extrahiert den Namen des Skripts / Prozesses, der mktemp ausgeführt hat. Wenn ich ein Skript habe, /home/jesse/scripts/myScript.shwird es $(basename $0)zurückgegeben, myScript.shwenn es von diesem Skript ausgeführt wird. So sind die oben genannten Befehle schaffen würde /run/user/1000/myScript.sh.w42BYxbG/und /run/user/1000/myScript.sh.w42BYxbG/myScript.sh.BCzSmq06jeweils.

Jesse der Windwanderer
quelle
/run/user/1000ist auf jedem Linux verfügbar, das systemd verwendet, daher ist es nicht nur auf debian-basierten Systemen verfügbar, sondern auch auf den meisten anderen Linux-Distributionen. Wenn nicht, sollte stattdessen / tmp verwendet werden. Sie können Ihre Befehle vereinfachen, indem Sie die Variable $ XDG_RUNTIME_DIR verwenden, die für jeden Benutzer bereits das richtige Verzeichnis enthält. Weitere Informationen finden Sie z. B. in dieser Antwort: unix.stackexchange.com/questions/162900/…
Alex
1
Benutze mkstemp über mktemp !! Grund von: linux.die.net/man/3/mktemp : in der Sektion Bugs "... jede Verwendung von mktemp () ist ein Sicherheitsrisiko. Das Rennen wird von mkstemp (3) vermieden."
Alex
0

Wie ich es verstehe, sind die Ziele: (1) Sie auf die Festplatte die Reversed - Datei speichern, an den Browser bedient werden (Anmerkung: diese tmpfs sein könnte, etc, da alle anderen Antworten bereits ausführlich); (2) Vermeiden Sie es jedoch, die erste tmp-Datei mit der ursprünglichen Ausgabe auf die Festplatte zu schreiben. und dennoch zeigt (3) immer noch die ursprüngliche Ausgabe auf stdout an.

In diesem Fall kann das Folgende Ihren Anforderungen mit der Bash-Prozessersetzung (dh im Grunde genommen einer Named Pipe) gerecht werden :

command | tee >( tac > /var/www/html/logs/scriptname.txt )

Beachten Sie, dass die Ausgabe kontinuierlich auf stdout gedruckt wird. Wenn der Befehl endet (wenn die Schleife beendet wird), wird die Ausgabe umgekehrt und in die Ausgabedatei geschrieben. Die folgende Abbildung gibt eine Zeile pro Sekunde aus. Nach Beendigung /tmp/foo.txtenthält die Datei die umgekehrten Zeilen:

i=0
while [ $i -lt 10 ]; do
    ((i = i+1))
    echo "==$i== $(date)"
    sleep 1
done | tee >( tac >> /tmp/foo.txt ) 
michael
quelle