Come creare un file temporaneo nella RAM?


29

Ho uno script che eseguirà il pipe del suo output |tee scriptnameYYMMDD.txt. Dopo ogni ciclo del ciclo for in cui viene generato l'output, invertirò il contenuto del file in tac scriptnameYYYYMMDD.txt > /var/www/html/logs/scriptname.txtmodo che l'output del registro sia visibile in una finestra del browser con le righe più recenti in alto.

Avrò diversi script che lo fanno in parallelo. Sto cercando di ridurre al minimo l'attività del disco, quindi l'output da |tee scriptnameYYYYMMDD.txtun disco RAM sarebbe il migliore. mktempcrea un file nella /tmpcartella, ma questo non sembra essere off-disk.


Deve essere un ramfs o un tmpfs (il secondo è meglio). Controlla se un tale fs è già montato sul tuo sistema, se sì puoi usarlo. In caso contrario, è necessario montarlo.
Peter dice di reintegrare Monica il

Aggiornerei fstabper montare un tmpfson /tmpe quindi riavviare il computer.
Kasperd,

1
potresti prendere in considerazione la possibilità di inserire taili file in modo incrementale (o avviarlo tramite CGI su richiesta o qualcosa del genere) piuttosto che taceseguire il tutto.
Mikeserv,

Questo sembra funzionare nei test (scusate per la formattazione ridotta): TEMPPATH="/ramdisk" LOGPATH="/var/www/html/log" ... echo <various calls to echo> | tee -a $TEMPPATH/moveKRT$(date '+%Y%m%d').txt ... alla fine di for loop, 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 sono consapevole della minuscola possibilità che il passaggio da 23: 59: 59.999 a 00:00: 00 può influire su alcuni file, ma la possibilità è accettabile.
user208145

Aggiornamento sui miei progressi su questo: ho un volume tmpfs da 1 GB montato su / ramdisk. Ho dei file che arrivano nelle cartelle home dell'utente via FTP. Vengono spostati in una sottocartella / ramdisk / queues / xyz / per essere elaborati e successivamente eliminati. All'avvio, ho uno script che ricrea la mia struttura di directory necessaria sotto / ramdisk. Ciò dovrebbe comportare un'attività minima del disco per i file in arrivo. Finora l'unico altro modo che vedo per ridurre l'I / O del disco per questi script sarebbe quello di creare quelle cartelle utente in un tmpfs creato all'avvio, prima che qualsiasi file arrivi tramite FTP a tali cartelle utente. Ringrazia tutti.
user208145

Risposte:


22

Puoi montare un tmpfspartititon e scrivere il file lì:

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

Questa partizione ora è limitata a 500 MB. Se il file temporaneo cresce più grande di 500 MB si verificherà un errore: no space left on device. Tuttavia, non importa quando si specifica una quantità di spazio maggiore rispetto alla RAM di sistema. tmpfsutilizza anche lo spazio di scambio, quindi non è possibile forzare un arresto anomalo del sistema, al contrario ramfs.

Ora puoi scrivere il tuo file in /mountpoint:

command | tee /mountpoint/scriptnameYYYYMMDD.txt

3
size=[num]%va anche bene - un tmpfs può essere limitato a una percentuale di memoria disponibile. In genere è più facile in questo modo se i comandi non sono sempre destinati alla stessa macchina (reale / virtuale) . Inoltre è utile che un tmpfs non elimini i contenuti con -o remount,size=newsize.
Mikeserv,

1
Poiché la domanda ruota attorno a uno script bash, che non abbiamo motivo di presumere sia gestito da root, puoi specificare se uno potrebbe aggirare mountnon consentendo agli utenti non root di utilizzare -to -o? Cioè, come si possono creare script che utilizzano tmpfs(o RAM in qualsiasi altro modo) per salvare su operazioni su disco, se un sistema adatto non esiste già sul sistema?
Jonathan Y.

Non è una buona risposta. Fallirà se non sei root.
Alex

11

Prova questo con Ubuntu:

ramtmp="$(mktemp -p /dev/shm/)"
tac scriptnameYYYYMMDD.txt > "$ramtmp"

3
quanto è stabile scrivere /run/shm/? Posso applicare le chmodmodifiche al file temporaneo se necessario? Ho notato che i bit di modalità della cartella sono identici alla /tmpcartella. Grazie.
user208145

1
Come per altre directory, i file generati in /run/shm(link simbolico a /dev/shm) mktemphanno anche un'autorizzazione predefinita di -rw-------(600) e puoi cambiarla se necessario con sudo chmod.
KrisWebDev

9

La seguente risposta è stata scoperta indagando le risposte precedenti e le informazioni in questa domanda qui e non sarebbero state trovate senza di esse. Complimenti a loro.

Sul mio sistema linuxmint (e presumo che la maggior parte dei sistemi basati su Ubuntu e forse anche su Debian) ci sia un tmpfs di proprietà dell'utente montato automaticamente su /run/user/1000/

Utilizzare df -Tper verificare.

11:41:11 jesse @ Limbo: ~ $ df -T
Tipo di file 1K-blocchi usati disponibili Usa% montato su
udev devtmpfs 15904812 4 15904808 1% / dev
tmpfs tmpfs 3184120 1700 3182420 1% / corsa
/ dev / sdb2 ext4 14248880 11464788 2037240 85% /
nessuno tmpfs 4 0 4 0% / sys / fs / cgroup
nessuno tmpfs 5120 0 5120 0% / corsa / blocco
nessuno tmpfs 15920584 848 15919736 1% / corsa / shm
nessuno tmpfs 102400 12 102388 1% / corsa / utente
/ dev / sdb3 ext4 100861352 90755700 4959136 95% / mnt / data

Sotto /run/user/c'è una directory per ogni normale utente sul sistema

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

Queste directory prendono il nome dagli ID dei rispettivi utenti. Possiamo ottenere l'ID utente con id -uvedere man idper i dettagli su questo comando.

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

Possiamo quindi usare il mktempcomando con l' --tmpdiropzione per creare file e directory temporanee in questo sistema di tempfiles creando così tempfile nella RAM.

Seguendo i consigli forniti qui creo prima una directory temporanea e quindi creo i miei file temporanei in questo modo:

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

per creare una directory temporanea /run/user/1000/bash.w42BYxbG/quindi

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

per creare un tempfile al suo interno.

Ciò semplifica la pulizia di questi file poiché tutto ciò che devo fare è rm -r $mydir.

Per impostazione predefinita, tutti questi file sono di proprietà e leggibili solo dall'utente che li ha creati.

Nota: la $(basename $0)parte del comando estrae il nome dello script / processo che ha eseguito mktemp. Se ho uno script /home/jesse/scripts/myScript.shpoi $(basename $0)restituisce myScript.shquando eseguito da questo script. Pertanto, i comandi precedenti creerebbero /run/user/1000/myScript.sh.w42BYxbG/e /run/user/1000/myScript.sh.w42BYxbG/myScript.sh.BCzSmq06rispettivamente.


/run/user/1000è disponibile su ogni Linux che utilizza systemd, quindi non è disponibile solo su sistemi basati su debian, ma anche sulla maggior parte delle altre distribuzioni di Linux. Altrimenti, dovrebbe essere usato / tmp. Puoi semplificare i tuoi comandi usando la variabile $ XDG_RUNTIME_DIR che mantiene già la directory corretta per ogni utente. Per maggiori informazioni, controlla ad esempio questa risposta: unix.stackexchange.com/questions/162900/…
Alex

1
Usa mkstemp su mktemp !! Motivo di: linux.die.net/man/3/mktemp : nella sezione Bugs "... ogni utilizzo di mktemp () è un rischio per la sicurezza, La gara è evitata da mkstemp (3)."
Alex

0

A quanto mi risulta, gli obiettivi sono: (1) non memorizzare il file invertita su disco, per essere servito al browser (nota: questo potrebbe essere tmpfs, ecc, come tutte le altre risposte già dettaglio); ma, (2) evitare di scrivere il primo file tmp su disco, con l'output originale; eppure, (3) mostra ancora l'output originale su stdout.

In tal caso, quindi quanto segue potrebbe soddisfare le tue esigenze, usando la sostituzione del processo bash (cioè, fondamentalmente una pipe denominata):

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

Si noti che questo stampa continuamente l'output su stdout e quando termina il comando (quando termina il ciclo), inverte l'output e lo scrive nel file di output. Illustrato tramite quanto segue, che stampa una riga al secondo e dopo la terminazione il file /tmp/foo.txtcontiene le righe invertite:

i=0
while [ $i -lt 10 ]; do
    ((i = i+1))
    echo "==$i== $(date)"
    sleep 1
done | tee >( tac >> /tmp/foo.txt ) 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.