web-dev-qa-db-fra.com

Comment créer un fichier temporaire en RAM?

J'ai un script qui dirigera sa sortie vers |tee scriptnameYYMMDD.txt. Après chaque cycle de la boucle for dans laquelle la sortie est générée, je vais inverser le contenu du fichier avec tac scriptnameYYYYMMDD.txt > /var/www/html/logs/scriptname.txt pour que la sortie du journal soit visible dans une fenêtre de navigateur avec les lignes les plus récentes en haut.

J'aurai plusieurs scripts faisant cela en parallèle. J'essaie de minimiser l'activité du disque, donc la sortie de |tee scriptnameYYYYMMDD.txt sur un disque RAM serait préférable. mktemp crée un fichier dans le /tmp dossier, mais qui ne semble pas être hors disque.

31
user208145

Vous pouvez monter une partition tmpfs et y écrire le fichier:

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

Cette partition est désormais limitée à 500 Mo. Si votre fichier temporaire dépasse 500 Mo, une erreur se produit: no space left on device. Mais cela n'a pas d'importance lorsque vous spécifiez une plus grande quantité d'espace que vos systèmes RAM has. tmpfs utilise aussi l'espace de swap, donc vous ne pouvez pas forcer un crash système, car par opposition à ramfs.

Vous pouvez maintenant écrire votre fichier dans /mountpoint:

command | tee /mountpoint/scriptnameYYYYMMDD.txt
24
chaos

Essayez ceci avec Ubuntu:

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

La réponse suivante a été découverte en examinant les réponses précédentes et les informations de cette question ici et n'aurait pas été trouvée sans elles. Cudos à eux.

Sur mon système linuxmint (et je suppose que la plupart des systèmes basés sur Ubuntu et peut-être aussi sur Debian) il y a un tmpfs appartenant à l'utilisateur monté automatiquement sur /run/user/1000/

Utilisez df -T Pour vérifier.

 11:41:11 jesse @ Limbo: ~ $ df -T 
 Type de système de fichiers 1K-blocks Utilisé Disponible Utiliser% Monté sur 
 Udev devtmpfs 15904812 4 15904808 1%/dev 
 tmpfs tmpfs 3184120 1700 3182420 1%/runun ._________ .] aucun tmpfs 5120 0 5120 0% /run/lockaucun tmpfs 102400 12 102388 1%/exécution/utilisateur
/dev/sdb3 ext4 100861352 90755700 4959136 95% /mnt/data

Sous /run/user/, Il y a un répertoire pour chaque utilisateur normal du système

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

Ces répertoires sont nommés d'après les identifiants de leurs utilisateurs respectifs. Nous pouvons obtenir l'ID utilisateur avec id -u Voir man id Pour plus de détails sur cette commande.

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

Nous pouvons ensuite utiliser la commande mktemp avec l'option --tmpdir Pour créer des fichiers et des répertoires temporaires dans ce système de fichiers temporaires, créant ainsi des fichiers temporaires dans la RAM.

En suivant les conseils donnés ici Je crée d'abord un répertoire temporaire puis je crée mes fichiers temporaires en cela:

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

pour créer un répertoire temporaire /run/user/1000/bash.w42BYxbG/ puis

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

pour y créer un fichier temporaire.

Cela facilite le nettoyage de ces fichiers car tout ce que j'ai à faire est rm -r $mydir.

Par défaut, tous ces fichiers sont détenus et lisibles uniquement par l'utilisateur qui les a créés.

Remarque: La partie $(basename $0) de la commande extrait le nom du script/processus qui a exécuté mktemp. Si j'ai un script /home/jesse/scripts/myScript.sh Alors $(basename $0) renvoie myScript.sh Lorsqu'il est exécuté par ce script. Ainsi, les commandes ci-dessus créeraient respectivement /run/user/1000/myScript.sh.w42BYxbG/ Et /run/user/1000/myScript.sh.w42BYxbG/myScript.sh.BCzSmq06.

Si je comprends bien, les objectifs sont les suivants: (1) stocker le fichier inversé sur le disque, pour être servi dans le navigateur (remarque: cela pourrait être tmpfs, etc, comme toutes les autres réponses le détaillent déjà); mais, (2) évitez d'écrire le premier fichier tmp sur le disque, avec la sortie d'origine; et pourtant, (3) affiche toujours la sortie d'origine sur stdout.

Si c'est le cas, alors ce qui suit pourrait répondre à vos besoins, en utilisant substitution de processus bash (c'est-à-dire, essentiellement un canal nommé):

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

Notez que cela imprime en continu la sortie vers stdout et lorsque la commande se termine (lorsque votre boucle se termine), inverse cette sortie et l'écrit dans le fichier de sortie. Illustré par ce qui suit, qui imprime une ligne par seconde, et après la fin du fichier /tmp/foo.txt contient les lignes inversées:

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