Jak zrobić plik tymczasowy w pamięci RAM?

29

Mam skrypt, do którego potokuje dane wyjściowe |tee scriptnameYYMMDD.txt. Po każdym cyklu pętli for, w której generowane jest wyjście, będę odwracał zawartość pliku tac scriptnameYYYYMMDD.txt > /var/www/html/logs/scriptname.txt, aby wynik dziennika był widoczny w oknie przeglądarki z najnowszymi wierszami u góry.

Będę miał kilka skryptów wykonujących to równolegle. Próbuję zminimalizować aktywność dysku, więc wyjście z dysku |tee scriptnameYYYYMMDD.txtRAM byłoby najlepsze. mktemptworzy plik w /tmpfolderze, ale nie wydaje się, aby znajdował się poza dyskiem.

użytkownik208145
źródło
Musi to być ramfs lub tmpfs (drugi jest lepszy). Sprawdź, czy taki fs jest już zamontowany w systemie, jeśli tak, możesz go użyć. Jeśli nie, musisz go zamontować.
Peter mówi, że przywraca Monikę
Chciałbym zaktualizować fstabw celu zamontowania tmpfsna /tmpi uruchom ponownie komputer.
kasperd
1
możesz rozważyć stopniowe tailtworzenie plików (lub inicjowanie ich za pomocą CGI na żądanie lub coś takiego) zamiast taccałości.
mikeserv
Wydaje się, że działa to podczas testowania (przepraszam za zmniejszone formatowanie): TEMPPATH="/ramdisk" LOGPATH="/var/www/html/log" ... echo <various calls to echo> | tee -a $TEMPPATH/moveKRT$(date '+%Y%m%d').txt ... na zakończenie pętli for, 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 mam świadomość niewielkiej możliwości, że zmiana z 23: 59: 59.999 na 00:00: 00 może wpływać na niektóre pliki, ale szansa jest do zaakceptowania.
user208145,
Zaktualizuj moje postępy w tej sprawie: Mam wolumin tmpfs 1 GB podłączony w / ramdisk. Mam pliki przychodzące do domowych folderów użytkownika przez FTP. Są one przenoszone do podfolderu / ramdysku / kolejek / xyz / w celu przetworzenia, a następnie usuwane. Podczas uruchamiania mam skrypt, który ponownie tworzy potrzebną strukturę katalogów w / ramdisk. Powinno to spowodować minimalną aktywność dysku dla przychodzących plików. Jak dotąd jedynym innym sposobem, jaki widzę w celu ograniczenia We / Wy dysku dla tych skryptów, byłoby utworzenie tych folderów użytkownika w tmpfs utworzonych podczas uruchamiania, zanim jakiekolwiek pliki wejdą przez FTP do tych folderów użytkownika. Dziękuje wszystkim.
user208145,

Odpowiedzi:

22

Możesz zamontować tmpfspartititon i tam zapisać plik:

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

Ta partycja jest teraz ograniczona do 500 MB. Jeśli plik tymczasowy rośnie większy niż 500 MB wystąpi błąd: no space left on device. Ale nie ma znaczenia, kiedy określisz więcej miejsca niż systemowa pamięć RAM. tmpfsużywa również przestrzeni wymiany, więc nie można wymusić awarii systemu, w przeciwieństwie do ramfs.

Możesz teraz zapisać swój plik w /mountpoint:

command | tee /mountpoint/scriptnameYYYYMMDD.txt
chaos
źródło
3
size=[num]%jest również w porządku - tmpfs można ograniczyć do procentu dostępnej pamięci. Zwykle jest to łatwiejsze, jeśli polecenia nie zawsze są skierowane do tej samej (rzeczywistej / wirtualnej) maszyny. Przydatne jest również to, że tmpfs nie upuszcza zawartości w / -o remount,size=newsize.
mikeserv
1
Ponieważ zapytania się obraca wokół skryptu bash, który nie mamy powodu przypuszczać, prowadzony jest przez roota, można określić, czy można obejść mountnie pozwalając użytkownikom innym niż root używać -talbo -o? To znaczy, jak budować skrypty, które używają tmpfs(lub RAM w jakikolwiek inny sposób), aby oszczędzać na operacjach na dysku, jeśli odpowiedni system plików nie istnieje jeszcze w systemie?
Jonathan Y.
Nie dobra odpowiedź. Nie powiedzie się, jeśli nie jesteś rootem.
Alex
11

Wypróbuj to z Ubuntu:

ramtmp="$(mktemp -p /dev/shm/)"
tac scriptnameYYYYMMDD.txt > "$ramtmp"
Cyrus
źródło
3
jak stabilne jest pisanie /run/shm/? Czy chmodw razie potrzeby mogę zastosować zmiany do pliku tymczasowego? Zauważyłem, że bity trybu folderu są identyczne z /tmpfolderem. dzięki.
user208145,
1
Podobnie jak w przypadku innych katalogów, pliki generowane w /run/shm(dowiązanie symboliczne /dev/shm) mktemprównież mają domyślne uprawnienie -rw-------(600) i można je zmienić w razie potrzeby za pomocą sudo chmod.
KrisWebDev
9

Poniższa odpowiedź została odkryta przez zbadanie poprzednich odpowiedzi i informacji zawartych w tym pytaniu tutaj i nie zostałaby znaleziona bez nich. Cudos do nich.

W moim systemie linuxmint (i zakładałbym, że większość systemów opartych na Ubuntu i prawdopodobnie również opartych na Debianie) istnieje tmpfs należący do użytkownika montowany automatycznie na /run/user/1000/

Użyj, df -Taby sprawdzić.

11:41:11 jesse @ Limbo: ~ $ df -T
Typ systemu plików Użyte bloki 1K Dostępne Użyj% Zamontowane
udev devtmpfs 15904812 4 15904808 1% / dev
tmpfs tmpfs 3184120 1700 3182420 1% / run
/ dev / sbb2 ext4 14248880 11464788 2037240 85% /
brak tmpfs 4 0 4 0% / sys / fs / cgroup
brak tmpfs 5120 0 5120 0% / run / lock
brak tmpfs 15920584 848 15919736 1% / run / shm
brak tmpfs 102400 12 102388 1% / run / user
/ dev / sbb3 ext4 100861352 90755700 4959136 95% / mnt / data

Poniżej /run/user/znajduje się katalog dla każdego normalnego użytkownika w systemie

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

Te katalogi są nazwane na podstawie identyfikatorów odpowiednich użytkowników. Możemy uzyskać identyfikator użytkownika za pomocą id -uzobacz man idszczegóły na temat tego polecenia.

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

Następnie możemy użyć mktemppolecenia z --tmpdiropcją tworzenia plików tymczasowych i katalogów w tym systemie plików tymczasowych, tworząc w ten sposób pliki tymczasowe w pamięci RAM.

Zgodnie z podanymi tutaj poradami najpierw tworzę katalog tymczasowy, a następnie tworzę w nim pliki tymczasowe:

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

utworzyć katalog temp /run/user/1000/bash.w42BYxbG/następnie

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

aby utworzyć w nim plik tymczasowy.

Ułatwia to czyszczenie tych plików, ponieważ wszystko, co muszę zrobić, to rm -r $mydir.

Domyślnie wszystkie te pliki są własnością i są czytelne tylko dla użytkownika, który je utworzył.

Uwaga: $(basename $0)Część polecenia wyodrębnia nazwę skryptu / procesu, który wykonał mktemp. Jeśli mam skrypt, /home/jesse/scripts/myScript.shto $(basename $0)wraca myScript.shpo wykonaniu przez ten skrypt. Zatem powyższe polecenia może stworzyć /run/user/1000/myScript.sh.w42BYxbG/i /run/user/1000/myScript.sh.w42BYxbG/myScript.sh.BCzSmq06odpowiednio.

Jesse the Wind Wanderer
źródło
/run/user/1000jest dostępny na każdym Linuksie, który używa systemd, więc jest dostępny nie tylko w systemach opartych na Debianie, ale także w większości innych dystrybucji Linuksa. Jeśli nie, zamiast tego należy użyć / tmp. Możesz uprościć swoje polecenia, używając zmiennej $ XDG_RUNTIME_DIR, która już utrzymuje prawidłowy katalog dla każdego użytkownika. Aby uzyskać więcej informacji, sprawdź np. Tę odpowiedź: unix.stackexchange.com/questions/162900/…
Alex
1
Użyj mkstemp zamiast mktemp !! Powód: linux.die.net/man/3/mktemp : w sekcji Błędy „... każde użycie mktemp () stanowi zagrożenie bezpieczeństwa, mkstemp (3) unika wyścigu”.
Alex
0

Jak rozumiem, cele są następujące: (1) czy zapisać plik na dysku odwrócony, aby Mu służono, w przeglądarce (Uwaga: to może być tmpfs, itp, jak wszystkie inne odpowiedzi już szczegół); ale (2) unikaj zapisywania pierwszego pliku tmp na dysk z oryginalnym wyjściem; a jednak (3) nadal wyświetla oryginalne wyjście na standardowe wyjście.

Jeśli tak, to następujące mogą spełniać twoje potrzeby, używając podstawienia procesu bash (tzn. W zasadzie nazwanego potoku):

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

Zauważ, że jest to ciągłe drukowanie wyjścia na standardowe wyjście, a gdy polecenie się kończy (kiedy pętla się kończy), odwraca to wyjście i zapisuje je w pliku wyjściowym. Zilustrowano to następująco, która drukuje jedną linię na sekundę, a po zakończeniu plik /tmp/foo.txtzawiera odwrócone linie:

i=0
while [ $i -lt 10 ]; do
    ((i = i+1))
    echo "==$i== $(date)"
    sleep 1
done | tee >( tac >> /tmp/foo.txt ) 
Michał
źródło