Как сделать временный файл в оперативной памяти?


29

У меня есть скрипт, который будет передавать его вывод |tee scriptnameYYMMDD.txt. После каждого цикла цикла for, в котором генерируется вывод, я буду поменять содержимое файла tac scriptnameYYYYMMDD.txt > /var/www/html/logs/scriptname.txtтак, чтобы вывод журнала был виден в окне браузера с самыми новыми строками вверху.

У меня будет несколько сценариев, делающих это параллельно. Я пытаюсь минимизировать активность диска, поэтому вывод с |tee scriptnameYYYYMMDD.txtRAM-диска был бы наилучшим. mktempсоздает файл в /tmpпапке, но это не похоже на диск.


Это должен быть ramfs или tmpfs (второй лучше). Проверьте, установлен ли такой fs в вашей системе, если да, вы можете использовать это. Если нет, вам нужно смонтировать его.
Петер говорит восстановить Монику

Я бы обновить fstab, чтобы смонтировать tmpfsна , /tmpа затем перезагрузить машину.
Касперд

1
Вы можете рассмотреть возможность постепенного tailдобавления файлов (или инициации его через CGI по запросу или что-то в этом роде), а не tacвсего этого.
mikeserv

Кажется, это работает в тестировании (извините за уменьшенное форматирование): TEMPPATH="/ramdisk" LOGPATH="/var/www/html/log" ... echo <various calls to echo> | tee -a $TEMPPATH/moveKRT$(date '+%Y%m%d').txt ... в конце цикла 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 небольшая вероятность того, что изменение с 23: 59: 59.999 на 00:00: 00 может повлиять на некоторые файлы, но вероятность приемлема.
user208145

Обновление о моем прогрессе в этом: у меня есть том 1 ГБ tmpfs, смонтированный в / ramdisk У меня есть файлы, поступающие в домашние папки пользователя через FTP. Они перемещаются в подпапку / ramdisk / queues / xyz / для обработки и впоследствии удаляются. При запуске у меня есть скрипт, который заново создает необходимую структуру каталогов в / ramdisk. Это должно привести к минимальной активности диска для входящих файлов. До сих пор единственный другой способ уменьшения дискового ввода-вывода для этих сценариев - создание этих пользовательских папок в tmpfs, созданных при запуске, до того, как какие-либо файлы поступят через FTP в эти пользовательские папки. Спасибо всем.
user208145

Ответы:


22

Вы можете смонтировать tmpfsраздел и записать туда файл:

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

Этот раздел теперь ограничен 500 МБ. Если ваш временный файл становится больше , чем 500 МБ возникает ошибка: no space left on device. Но это не имеет значения, когда вы указываете больший объем памяти, чем у вашей системы. tmpfsтакже использует пространство подкачки, поэтому вы не можете вызвать сбой системы, в отличие от ramfs.

Теперь вы можете написать свой файл в /mountpoint:

command | tee /mountpoint/scriptnameYYYYMMDD.txt

3
size=[num]%тоже хорошо - tmpfs может быть ограничен процентом доступной памяти. Обычно это проще сделать, если команды не всегда предназначены для одной и той же (реальной / виртуальной) машины. Также удобно, что tmpfs не удаляет содержимое с / -o remount,size=newsize.
mikeserv

1
Поскольку вопрос вращается вокруг Баш скрипт, который мы не имеем никаких оснований полагать , управляет корнем, вы можете указать , может ли один обойти mountне позволяя пользователям некорневых использовать -tили -o? То есть, как можно создавать сценарии, которые используют tmpfs(или ОЗУ любым другим способом) для экономии на операциях на диске, если подходящая файловая система еще не существует в системе?
Джонатан Я.

Не очень хороший ответ. Сбой, если вы не root.
Алекс

11

Попробуйте это с Ubuntu:

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

3
насколько стабильна запись в /run/shm/? Могу ли я применить chmodизменения к временному файлу при необходимости? Я заметил, что биты режима папки идентичны /tmpпапке. Спасибо.
user208145

1
Что касается других каталогов, файлы, созданные в /run/shm(symlink to /dev/shm), mktempтакже имеют разрешение по умолчанию -rw-------(600), и вы можете изменить его при необходимости с помощью sudo chmod.
KrisWebDev

9

Следующий ответ был обнаружен путем изучения предыдущих ответов и информации в этом вопросе здесь, и не было бы найдено без них. Слава им.

В моей системе linuxmint (и я бы предположил, что большинство систем на основе Ubuntu и, возможно, на основе Debian) есть пользовательские tmpfs, автоматически смонтированные на /run/user/1000/

Используйте df -Tдля проверки.

11:41:11 jesse @ Limbo: ~ $ df -T
Тип файловой системы 1K-блоков Используется Доступно Использовать% Установлено на
udev devtmpfs 15904812 4 15904808 1% / dev
tmpfs tmpfs 3184120 1700 3182420 1% / пробег
/ dev / sdb2 ext4 14248880 11464788 2037240 85% /
нет tmpfs 4 0 4 0% / sys / fs / cgroup
нет tmpfs 5120 0 5120 0% / запуск / блокировка
нет tmpfs 15920584 848 15919736 1% / пробег / шм
нет tmpfs 102400 12 102388 1% / прогон / пользователь
/ dev / sdb3 ext4 100861352 90755700 4959136 95% / mnt / data

В разделе /run/user/есть каталог для каждого обычного пользователя в системе.

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

Эти каталоги названы в соответствии с их идентификаторами пользователя. Мы можем получить идентификатор пользователя, id -uсм. man idПодробности об этой команде.

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

Затем мы можем использовать mktempкоманду с --tmpdirопцией для создания временных файлов и каталогов в этой системе временных файлов, создавая тем самым временные файлы в оперативной памяти.

Следуя приведенному здесь совету, я сначала создаю временный каталог, а затем создаю свои временные файлы в нем:

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

создать временную папку , /run/user/1000/bash.w42BYxbG/то

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

создать временный файл в нем.

Это делает очистку этих файлов легкой, поскольку все, что мне нужно сделать, это rm -r $mydir.

По умолчанию все эти файлы принадлежат и доступны для чтения только пользователю, который их создал.

Примечание. $(basename $0)Часть команды извлекает имя сценария / процесса, который выполнил mktemp. Если у меня есть сценарий, /home/jesse/scripts/myScript.shто $(basename $0)возвращается, myScript.shкогда выполняется этот сценарий. Таким образом вышеприведенные команды будут создавать /run/user/1000/myScript.sh.w42BYxbG/и /run/user/1000/myScript.sh.w42BYxbG/myScript.sh.BCzSmq06соответственно.


/run/user/1000доступно в каждом linux, использующем systemd, поэтому оно доступно не только в системах на основе debian, но и в большинстве других дистрибутивов linux. Если нет, вместо этого следует использовать / tmp. Вы можете упростить ваши команды, используя переменную $ XDG_RUNTIME_DIR, которая уже содержит правильный каталог для каждого пользователя. Для получения дополнительной информации, проверьте, например, этот ответ: unix.stackexchange.com/questions/162900/…
Alex

1
Используйте mkstemp поверх mktemp !! Причина: linux.die.net/man/3/mktemp : в разделе «Ошибки»: «каждое использование mktemp () представляет собой угрозу безопасности. Mkstemp (3) избегает гонки.»
Алекс

0

Как я понимаю, эти цели являются: (1) действительно сохранить перевернутый файл на диск, который будет поданы в браузер (примечание: это может быть TMPFS и т.д., как и все другие ответы уже подробно); но (2) избегайте записи первого файла tmp на диск с исходным выводом; и все же, (3) по-прежнему отображать исходный вывод на стандартный вывод.

Если это так, то следующее может удовлетворить ваши потребности, используя замену процесса bash (то есть, в основном, именованный канал):

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

Обратите внимание, что это непрерывная печать вывода в stdout, и когда команда заканчивается (когда ваш цикл завершается), инвертирует этот вывод и записывает его в выходной файл. Проиллюстрировано следующим образом, который печатает одну строку в секунду, а после завершения файл /tmp/foo.txtсодержит перевернутые строки:

i=0
while [ $i -lt 10 ]; do
    ((i = i+1))
    echo "==$i== $(date)"
    sleep 1
done | tee >( tac >> /tmp/foo.txt ) 
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.