Bagaimana cara membuat file sementara di RAM?

29

Saya memiliki skrip yang akan mengirimkan outputnya ke |tee scriptnameYYMMDD.txt. Setelah setiap siklus loop for di mana output dihasilkan, saya akan membalikkan isi file dengan tac scriptnameYYYYMMDD.txt > /var/www/html/logs/scriptname.txtsehingga output log terlihat di jendela browser dengan baris terbaru di atas.

Saya akan meminta beberapa skrip melakukan ini secara paralel. Saya mencoba meminimalkan aktivitas disk, jadi output dari |tee scriptnameYYYYMMDD.txtke RAMdisk akan lebih baik. mktempmembuat file di /tmpfolder, tetapi itu tampaknya tidak off-disk.

pengguna208145
sumber
Itu harus menjadi ramf atau tmpfs (kedua lebih baik). Periksa apakah fs tersebut sudah terpasang pada sistem Anda, jika ya Anda dapat menggunakannya. Jika tidak, Anda harus memasangnya.
peterh mengatakan mengembalikan Monica
Aku akan memperbarui fstabuntuk me-mount tmpfspada /tmpdan kemudian reboot mesin.
kasperd
1
Anda mungkin mempertimbangkan tailuntuk menambahkan file secara bertahap (atau memprakarsai melalui CGI atas permintaan atau sesuatu) daripada tacmelakukan semuanya.
mikeserv
Ini tampaknya bekerja dalam pengujian (maaf untuk pemformatan yang berkurang): TEMPPATH="/ramdisk" LOGPATH="/var/www/html/log" ... echo <various calls to echo> | tee -a $TEMPPATH/moveKRT$(date '+%Y%m%d').txt ... pada akhir untuk loop, saya tahu 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 saya kemungkinan kecil bahwa perubahan dari 23: 59: 59,999 menjadi 00:00: 00 dapat memengaruhi beberapa file, tetapi peluangnya dapat diterima.
user208145
Perbarui kemajuan saya dalam hal ini: Saya memiliki volume 1 GB tmpfs yang terpasang di / ramdisk. Saya memiliki file yang masuk ke folder home user melalui FTP. Mereka dipindahkan ke subfolder / ramdisk / antrian / xyz / untuk diproses dan dihapus setelahnya. Saat startup, saya memiliki skrip yang membuat ulang struktur direktori yang saya butuhkan di bawah / ramdisk. Ini akan menghasilkan aktivitas disk minimal untuk file yang masuk. Sejauh ini satu-satunya cara lain yang saya lihat untuk mengurangi disk I / O untuk skrip ini adalah dengan membuat folder pengguna dalam tmpfs yang dibuat saat startup, sebelum file masuk melalui FTP ke folder pengguna tersebut. Terima kasih semuanya.
user208145

Jawaban:

22

Anda dapat me-mount tmpfspartisi dan menulis file di sana:

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

Partisi ini sekarang dibatasi hingga 500 MB. Jika file sementara Anda tumbuh lebih besar dari 500 MB kesalahan akan terjadi: no space left on device. Tapi, tidak masalah ketika Anda menentukan jumlah ruang yang lebih besar daripada yang dimiliki RAM sistem Anda. tmpfsmenggunakan ruang swap juga, jadi Anda tidak bisa memaksakan sistem crash, sebagai lawannya ramfs.

Anda sekarang dapat menulis file Anda ke /mountpoint:

command | tee /mountpoint/scriptnameYYYYMMDD.txt
kekacauan
sumber
3
size=[num]%juga baik - tmpfs dapat dibatasi hingga persentase memori yang tersedia. Biasanya lebih mudah seperti itu jika perintah tidak selalu ditargetkan untuk mesin (nyata / virtual) yang sama . Juga berguna adalah bahwa tmpfs tidak menjatuhkan konten dengan / -o remount,size=newsize.
mikeserv
1
Karena pertanyaan berputar di sekitar skrip bash, yang kami tidak punya alasan untuk menganggapnya dijalankan oleh root, dapatkah Anda menentukan apakah seseorang dapat berkeliling mounttanpa mengizinkan pengguna non-root untuk menggunakan -tatau -o? Yaitu, bagaimana caranya membuat skrip yang menggunakan tmpfs(atau RAM dengan cara lain) untuk menghemat operasi disk, jika sistem file yang sesuai belum ada pada sistem?
Jonathan Y.
Bukan jawaban yang bagus. Akan gagal jika Anda tidak root.
Alex
11

Coba ini dengan Ubuntu:

ramtmp="$(mktemp -p /dev/shm/)"
tac scriptnameYYYYMMDD.txt > "$ramtmp"
Cyrus
sumber
3
seberapa stabilkah penulisan /run/shm/? Bisakah saya menerapkan chmodperubahan pada file sementara jika diperlukan? Saya perhatikan bahwa bit mode folder identik dengan /tmpfolder. Terima kasih.
user208145
1
Adapun direktori lain, file yang dihasilkan di /run/shm(symlink to /dev/shm) oleh mktempjuga memiliki izin default -rw-------(600) dan Anda dapat mengubahnya jika diperlukan dengan sudo chmod.
KrisWebDev
9

Jawaban berikut ditemukan dengan menyelidiki jawaban sebelumnya dan info dalam pertanyaan ini di sini dan tidak akan ditemukan tanpa jawaban itu. Cudos kepada mereka.

Pada sistem linuxmint saya (dan saya akan menganggap sebagian besar sistem berbasis ubuntu dan mungkin berbasis debian juga) ada tmpfs milik pengguna yang dipasang secara otomatis pada /run/user/1000/

Gunakan df -Tuntuk memeriksa.

11:41:11 jesse @ Limbo: ~ $ df -T
Sistem File Tipe 1K-blok Digunakan Tersedia Gunakan% Dipasang di
udev devtmpfs 15904812 4 15904808 1% / dev
tmpfs tmpfs 3184120 1700 3182420 1% / jalankan
/ dev / sdb2 ext4 14248880 11464788 2037240 85% /
tidak ada tmpfs 4 0 4 0% / sys / fs / cgroup
tidak ada tmpfs 5120 0 5120 0% / run / lock
tidak ada tmpfs 15920584 848 15919736 1% / run / shm
tidak ada tmpfs 102400 12 102388 1% / run / pengguna
/ dev / sdb3 ext4 100861352 90755700 4959136 95% / mnt / data

Di bawah ini /run/user/ada direktori untuk setiap pengguna normal pada sistem

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

Direktori ini dinamai sesuai id pengguna masing-masing. Kita bisa mendapatkan id pengguna dengan id -umelihat man iddetail pada perintah ini.

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

Kita kemudian dapat menggunakan mktempperintah dengan --tmpdiropsi untuk membuat file temp dan direktori dalam sistem tempfiles ini sehingga membuat tempfile dalam RAM.

Mengikuti saran yang diberikan di sini saya membuat direktori temp terlebih dahulu dan kemudian membuat file temp saya di dalamnya:

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

untuk membuat direktori temp /run/user/1000/bash.w42BYxbG/lalu

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

untuk membuat tempfile di dalamnya.

Ini membuat membersihkan file ini mudah karena yang harus saya lakukan adalah rm -r $mydir.

Secara default semua file ini dimiliki dan hanya dapat dibaca oleh pengguna yang membuatnya.

Catatan: $(basename $0)Bagian dari perintah mengekstrak nama skrip / proses yang mengeksekusi mktemp. Jika saya memiliki skrip /home/jesse/scripts/myScript.shmaka $(basename $0)kembali myScript.shketika dijalankan oleh skrip ini. Dengan demikian perintah di atas akan membuat /run/user/1000/myScript.sh.w42BYxbG/dan /run/user/1000/myScript.sh.w42BYxbG/myScript.sh.BCzSmq06masing - masing.

Jesse si Pengembara Angin
sumber
/run/user/1000tersedia di setiap linux yang menggunakan systemd, jadi tidak hanya tersedia di sistem berbasis debian, tetapi juga di sebagian besar distribusi linux lainnya. Jika tidak, / tmp harus digunakan sebagai gantinya. Anda dapat menyederhanakan perintah Anda dengan menggunakan variabel $ XDG_RUNTIME_DIR yang sudah menyimpan direktori yang benar untuk setiap pengguna. Untuk info lebih lanjut, periksa misalnya jawaban ini: unix.stackexchange.com/questions/162900/…
Alex
1
Gunakan mkstemp lebih dari mktemp !! Alasan dari: linux.die.net/man/3/mktemp : di bagian Bug "... setiap penggunaan mktemp () adalah risiko keamanan, Perlombaan dihindari oleh mkstemp (3)."
Alex
0

Seperti yang saya mengerti, tujuan adalah: (1) jangan menyimpan file terbalik ke disk, untuk dilayani ke browser (catatan: ini bisa menjadi tmpfs, dll, karena semua jawaban yang lain sudah rinci); tetapi, (2) hindari menulis file tmp pertama ke disk, dengan output asli; namun, (3) masih menampilkan output asli ke stdout.

Jika demikian, maka yang berikut mungkin memenuhi kebutuhan Anda, menggunakan substitusi proses bash (yaitu, pada dasarnya pipa bernama):

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

Perhatikan bahwa ini terus mencetak output ke stdout, dan ketika perintah berakhir (ketika loop Anda berakhir), membalikkan output itu dan menulisnya ke file output. Diilustrasikan melalui yang berikut ini, yang mencetak satu baris per detik, dan setelah penghentian, file /tmp/foo.txtberisi baris yang terbalik:

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