จะสร้างไฟล์ชั่วคราวใน RAM ได้อย่างไร?


29

|tee scriptnameYYMMDD.txtฉันมีสคริปต์ที่จะท่อส่งออกไปยัง หลังจากแต่ละรอบของ for for loop ที่สร้างเอาต์พุตขึ้นมาฉันจะย้อนกลับเนื้อหาไฟล์ด้วยtac scriptnameYYYYMMDD.txt > /var/www/html/logs/scriptname.txtเพื่อให้สามารถเห็นเอาต์พุตบันทึกในหน้าต่างเบราว์เซอร์ที่มีบรรทัดใหม่ล่าสุดอยู่ด้านบน

ฉันจะมีสคริปต์หลายตัวที่ทำสิ่งนี้ควบคู่กัน ฉันพยายามลดกิจกรรมของดิสก์ให้น้อยที่สุดดังนั้นผลลัพธ์จาก|tee scriptnameYYYYMMDD.txtRAMdisk จะดีที่สุด mktempสร้างไฟล์ใน/tmpโฟลเดอร์ แต่ไม่ปรากฏว่าเป็นดิสก์


ต้องเป็น ramfs หรือ tmpfs (ที่สองดีกว่า) ตรวจสอบว่ามีการติดตั้ง fs บนระบบของคุณแล้วหรือไม่ถ้าใช่คุณสามารถใช้มันได้ ถ้าไม่คุณต้องติดตั้ง
peterh กล่าวว่าคืนสถานะโมนิก้า

ฉันต้องการอัปเดตfstabในการสั่งซื้อที่จะติดtmpfsบน/tmpแล้วรีบูตเครื่อง
kasperd

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 ... เมื่อเสร็จสิ้นการวนรอบฉันมี 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 ฉันตระหนักถึงความเป็นไปได้ miniscule ที่เปลี่ยนจาก 23: 59: 59.999 เป็น 00:00: 00 อาจส่งผลกระทบต่อบางไฟล์ แต่โอกาสเป็นที่ยอมรับ
user208145

ความคืบหน้าการปรับปรุงของฉันเกี่ยวกับเรื่องนี้: ฉันมีปริมาณ 1 GB tmpfs ติดตั้งที่ / ramdisk ฉันมีไฟล์เข้ามาในโฟลเดอร์โฮมของผู้ใช้ผ่าน FTP พวกเขาจะถูกย้ายไปยังโฟลเดอร์ย่อย / ramdisk / queues / xyz / เพื่อประมวลผลและถูกลบหลังจากนั้น เมื่อเริ่มต้นฉันมีสคริปต์ที่สร้างโครงสร้างไดเรกทอรีที่ต้องการอีกครั้งภายใต้ / ramdisk ซึ่งจะส่งผลให้กิจกรรมดิสก์น้อยที่สุดสำหรับไฟล์ที่เข้ามา จนถึงวิธีเดียวที่ฉันเห็นเพื่อลดดิสก์ I / O สำหรับสคริปต์เหล่านี้จะสร้างโฟลเดอร์ผู้ใช้เหล่านั้นใน tmpfs ที่สร้างขึ้นเมื่อเริ่มต้นก่อนที่ไฟล์ใด ๆ เข้ามาผ่าน FTP ไปยังโฟลเดอร์ผู้ใช้เหล่านั้น ขอบคุณทุกคน
user208145

คำตอบ:


22

คุณสามารถเมาtmpfsต์พาร์ทิชันและเขียนไฟล์ที่นั่น:

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

ขณะนี้พาร์ติชันนี้ถูก จำกัด ไว้ที่ 500 MB หากไฟล์ชั่วคราวของคุณเติบโตขึ้นมีขนาดใหญ่กว่า 500 MB no space left on deviceข้อผิดพลาดที่จะเกิดขึ้น: แต่มันไม่สำคัญว่าเมื่อคุณระบุพื้นที่ที่มีขนาดใหญ่กว่า RAM ระบบของคุณ tmpfsใช้พื้นที่สว็อปด้วยดังนั้นคุณจึงไม่สามารถบังคับให้ระบบขัดข้องramfsได้

ตอนนี้คุณสามารถเขียนไฟล์ของคุณลงใน/mountpoint:

command | tee /mountpoint/scriptnameYYYYMMDD.txt

3
size=[num]%ก็ดี - tmpfs สามารถถูก จำกัด เปอร์เซ็นต์ของหน่วยความจำที่มีอยู่ มันมักจะเป็นวิธีที่ง่ายขึ้นว่าหากคำสั่งไม่ได้กำหนดเป้าหมายเสมอสำหรับเดียวกัน(จริง / เสมือน)เครื่อง นอกจากนี้ยังมีประโยชน์เป็นที่ tmpfs ไม่ได้ลดลงเนื้อหา w -o remount,size=newsize/
mikeserv

1
เนื่องจากคำถามหมุนรอบสคริปต์ทุบตีซึ่งเราไม่มีเหตุผลที่จะถือว่าถูกเรียกใช้โดยรูทคุณสามารถระบุได้หรือไม่ว่าmountผู้ใช้ที่ไม่ใช่รูทสามารถใช้งาน-tหรือ-oไม่? กล่าวคือจะสร้างสคริปต์ที่ใช้tmpfs(หรือ RAM ในลักษณะอื่นใด) เพื่อบันทึกการทำงานของดิสก์ได้อย่างไรหากระบบไฟล์ที่เหมาะสมยังไม่มีอยู่ในระบบ
Jonathan Y.

ไม่ใช่คำตอบที่ดี จะล้มเหลวหากคุณไม่รูท
Alex

11

ลองสิ่งนี้กับ Ubuntu:

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

3
การเขียนมีความเสถียรเพียง/run/shm/ใด ฉันสามารถใช้chmodการเปลี่ยนแปลงกับไฟล์ชั่วคราวได้ไหมถ้าจำเป็น? ฉันสังเกตว่าบิตโหมดของโฟลเดอร์นั้นเหมือนกับ/tmpโฟลเดอร์ ขอบคุณ
user208145

1
สำหรับไดเรกทอรีอื่น ๆ , ไฟล์ที่สร้างขึ้นใน/run/shm(symlink ไป/dev/shm) โดยmktempยังมีสิทธิ์เริ่มต้นของ-rw-------(600) sudo chmodและคุณสามารถเปลี่ยนได้หากมีความจำเป็นด้วย
KrisWebDev

9

คำตอบต่อไปนี้ถูกค้นพบโดยการตรวจสอบคำตอบก่อนหน้าและข้อมูลในคำถามนี้ที่นี่และจะไม่ถูกค้นพบหากไม่มีพวกเขา ขอชื่นชมพวกเขา

ในระบบ linuxmint ของฉัน (และฉันจะถือว่าเป็นระบบที่ใช้ Ubuntu ส่วนใหญ่และอาจเป็นเดเบียนด้วย) มี 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% / run / lock
ไม่มี tmpfs 15920584 848 15919736 1% / run / shm
ไม่มี tmpfs 102400 12 102388 1% / run / user
/ 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ตัวเลือกในการสร้างไฟล์ชั่วคราวและไดเรกทอรีในระบบ tempfiles นี้ซึ่งเป็นการสร้าง tempfiles ใน RAM

ทำตามคำแนะนำที่นี่ฉันสร้างไดเรกทอรีชั่วคราวก่อนแล้วสร้างไฟล์ชั่วคราวของฉันในที่:

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

เพื่อสร้างไดเรกทอรีชั่วคราว/run/user/1000/bash.w42BYxbG/แล้ว

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

เพื่อสร้าง tempfile ในนั้น

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สามารถใช้งานได้บนแต่ละลินุกซ์ที่ใช้ systemd ดังนั้นมันจึงไม่สามารถใช้ได้เฉพาะกับระบบที่ใช้เดเบียนเท่านั้น ถ้าไม่ใช่ควรใช้ / tmp แทน คุณสามารถทำให้คำสั่งของคุณง่ายขึ้นโดยใช้ตัวแปร $ XDG_RUNTIME_DIR ซึ่งเก็บไดเรกทอรีที่ถูกต้องสำหรับผู้ใช้แต่ละคนไว้แล้ว สำหรับข้อมูลเพิ่มเติมให้ตรวจสอบเช่นคำตอบนี้: unix.stackexchange.com/questions/162900/…
อเล็กซ์

1
ใช้ mkstemp มากกว่า mktemp !! เหตุผลจาก: linux.die.net/man/3/mktemp : ในหัวข้อ Bugs "... การใช้ mktemp () ทุกครั้งมีความเสี่ยงด้านความปลอดภัยการแข่งขันจะถูกหลีกเลี่ยงโดย mkstemp (3)"
Alex

0

ตามที่ผมเข้าใจมันเป้าหมายคือ (1) ไม่เก็บไฟล์แบบผันกลับไปยังดิสก์ที่จะทำหน้าที่ในการเบราว์เซอร์ (หมายเหตุ: นี้อาจจะ tmpfs ฯลฯ เป็นทุกคำตอบอื่น ๆ รายละเอียดแล้ว); แต่, (2) หลีกเลี่ยงการเขียนไฟล์ tmp แรกไปยังดิสก์, ด้วยเอาต์พุตต้นฉบับ; และยัง (3) ยังคงแสดงเอาต์พุตต้นฉบับไปยัง stdout

หากเป็นเช่นนั้นสิ่งต่อไปนี้อาจตอบสนองความต้องการของคุณโดยใช้การทดแทนกระบวนการทุบตี (เช่นโดยทั่วไปแล้วเป็นไพพ์ที่มีชื่อ):

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 ) 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.