Làm thế nào để tạo một tập tin tạm thời trong RAM?


29

Tôi có một kịch bản sẽ dẫn đầu ra của nó |tee scriptnameYYMMDD.txt. Sau mỗi chu kỳ của vòng lặp for trong đó đầu ra được tạo, tôi sẽ đảo ngược nội dung tệp tac scriptnameYYYYMMDD.txt > /var/www/html/logs/scriptname.txtđể đầu ra nhật ký hiển thị trong cửa sổ trình duyệt với các dòng mới nhất ở trên cùng.

Tôi sẽ có một số kịch bản làm điều này song song. Tôi đang cố gắng giảm thiểu hoạt động của đĩa, vì vậy đầu ra từ |tee scriptnameYYYYMMDD.txtRAMdisk là tốt nhất. mktemptạo một tệp trong /tmpthư mục, nhưng dường như không phải là đĩa.


Nó cần phải là một ramfs hoặc một tmpfs (thứ hai là tốt hơn). Kiểm tra xem một fs như vậy đã được gắn trên hệ thống của bạn chưa, nếu có, bạn có thể sử dụng nó. Nếu không, bạn cần phải gắn kết nó.
peterh nói phục hồi Monica

Tôi muốn cập nhật fstabđể gắn kết một tmpfstrên /tmpvà sau đó khởi động lại máy.
kasperd

1
bạn có thể xem xét tăng dần tailcác tệp (hoặc khởi tạo nó thông qua CGI theo yêu cầu hoặc một cái gì đó) thay vì tacing toàn bộ.
mikeerv 6/03/2015

Điều này dường như hoạt động trong thử nghiệm (xin lỗi vì định dạng giảm dần): TEMPPATH="/ramdisk" LOGPATH="/var/www/html/log" ... echo <various calls to echo> | tee -a $TEMPPATH/moveKRT$(date '+%Y%m%d').txt ... khi kết thúc vòng lặp, tôi 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 biết rằng khả năng rất nhỏ là thay đổi từ 23: 59: 59.999 đến 00:00: 00 có thể ảnh hưởng đến một số tệp, nhưng cơ hội có thể chấp nhận được.
dùng208145

Cập nhật tiến trình của tôi về điều này: Tôi có dung lượng tmpfs 1 GB được gắn tại / ramdisk. Tôi có tập tin vào thư mục nhà của người dùng thông qua FTP. Chúng được chuyển đến thư mục con / ramdisk / hàng đợi / xyz / để xử lý và bị xóa sau đó. Khi khởi động, tôi có một tập lệnh tạo lại cấu trúc thư mục cần thiết của tôi trong / ramdisk. Điều này sẽ dẫn đến hoạt động đĩa tối thiểu cho các tệp đến. Cho đến nay, cách duy nhất khác tôi thấy để giảm I / O đĩa cho các tập lệnh này là tạo các thư mục người dùng đó trong một tmpfs được tạo khi khởi động, trước khi bất kỳ tệp nào đi qua FTP vào các thư mục người dùng đó. Cảm ơn tất cả.
dùng208145

Câu trả lời:


22

Bạn có thể gắn một tmpfspartititon và viết tệp ở đó:

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

Phân vùng này hiện bị giới hạn ở 500 MB. Nếu tệp tạm thời của bạn lớn hơn 500 MB, sẽ xảy ra lỗi : no space left on device. Nhưng, điều đó không thành vấn đề khi bạn chỉ định dung lượng lớn hơn dung lượng RAM hệ thống của bạn. tmpfssử dụng không gian hoán đổi quá, vì vậy bạn không thể buộc sự cố hệ thống, trái ngược với ramfs.

Bây giờ bạn có thể viết tập tin của bạn vào /mountpoint:

command | tee /mountpoint/scriptnameYYYYMMDD.txt

3
size=[num]%cũng tốt - một tmpfs có thể được giới hạn ở một tỷ lệ phần trăm bộ nhớ khả dụng. Nó thường dễ dàng hơn nếu các lệnh không phải luôn luôn được nhắm mục tiêu cho cùng một máy (thực / ảo) . Cũng tiện dụng là một tmpfs không bỏ nội dung w / -o remount,size=newsize.
mikeerv 6/03/2015

1
Vì câu hỏi xoay quanh một tập lệnh bash, mà chúng tôi không có lý do gì để cho rằng nó được chạy bởi root, bạn có thể chỉ định liệu người ta có thể đi xung quanh mountkhông cho phép người dùng không sử dụng root -thay -okhông? Đó là, làm thế nào một người có thể xây dựng các tập lệnh sử dụng tmpfs(hoặc RAM theo bất kỳ cách nào khác) để tiết kiệm cho các hoạt động của đĩa, nếu một hệ thống tệp phù hợp không tồn tại trên hệ thống?
Jonathan Y.

Không phải là một câu trả lời tốt. Sẽ thất bại nếu bạn không root.
Alex

11

Hãy thử điều này với Ubuntu:

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

3
Làm thế nào ổn định là viết đến /run/shm/? Tôi có thể áp dụng các chmodthay đổi cho tệp tạm thời nếu cần không? Tôi nhận thấy rằng các bit chế độ của thư mục giống hệt với /tmpthư mục. cảm ơn.
dùng208145

1
Đối với các thư mục khác, các tệp được tạo trong /run/shm(symlink đến /dev/shm) mktempcũng có quyền mặc định là -rw-------(600) và bạn có thể thay đổi nó nếu cần sudo chmod.
KrisWebDev

9

Câu trả lời sau đây được phát hiện bằng cách điều tra các câu trả lời trước đó và thông tin trong câu hỏi này ở đây và sẽ không được tìm thấy nếu không có chúng. Cudos cho họ.

Trên hệ thống linuxmint của tôi (và tôi sẽ giả sử hầu hết các hệ thống dựa trên Ubuntu và có thể dựa trên debian nữa) có một tmpfs do người dùng sở hữu được gắn tự động vào /run/user/1000/

Sử dụng df -Tđể kiểm tra.

11:41:11 jlie @ Limbo: ~ $ df -T
Loại hệ thống tập tin Loại 1K ​​được sử dụng Có sẵn Sử dụng% Được gắn trên
udev devtmpfs 15904812 4 15904808 1% / dev
tmpfs tmpfs 3184120 1700 3182420 1% / lần chạy
/ dev / sdb2 ext4 14248880 11464788 2037240 85% /
không có tmpfs 4 0 4 0% / sys / fs / cgroup
không tmpfs 5120 0 5120 0% / chạy / khóa
không có tmpfs 15920584 848 15919736 1% / lần chạy / shm
không có tmpfs 102400 12 102388 1% / lần chạy / người dùng
/ dev / sdb3 ext4 100861352 90755700 4959136 95% / mnt / dữ liệu

Bên dưới /run/user/có một thư mục cho mỗi người dùng bình thường trên hệ thống

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

Các thư mục này được đặt tên theo id người dùng tương ứng của họ. Chúng ta có thể lấy id người dùng để id -uxem man idchi tiết về lệnh này.

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

Sau đó chúng ta có thể sử dụng mktemplệnh với --tmpdirtùy chọn để tạo các tệp và thư mục tạm thời trong hệ thống tempfiles này, do đó tạo tempfiles trong RAM.

Theo lời khuyên được đưa ra ở đây, trước tiên tôi tạo một thư mục tạm thời và sau đó tạo các tệp tạm thời của mình trong đó:

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

để tạo ra một thư mục tạm /run/user/1000/bash.w42BYxbG/rồi

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

để tạo một tempfile trong đó.

Điều này làm cho việc dọn dẹp các tệp này dễ dàng vì tất cả những gì tôi phải làm là rm -r $mydir.

Theo mặc định, tất cả các tệp này được sở hữu và chỉ có thể đọc được bởi người dùng đã tạo chúng.

Lưu ý: $(basename $0)Phần của lệnh trích xuất tên của tập lệnh / tiến trình đã thực hiện mktemp. Nếu tôi có một tập lệnh /home/jesse/scripts/myScript.shthì $(basename $0)trả về myScript.shkhi được thực thi bởi tập lệnh này. Do đó, các lệnh trên sẽ tạo /run/user/1000/myScript.sh.w42BYxbG//run/user/1000/myScript.sh.w42BYxbG/myScript.sh.BCzSmq06tương ứng.


/run/user/1000có sẵn trên mỗi linux sử dụng systemd, vì vậy nó không chỉ có sẵn trên các hệ thống dựa trên debian, mà còn trên hầu hết các bản phân phối linux khác. Nếu không, / tmp nên được sử dụng thay thế. Bạn có thể đơn giản hóa các lệnh của mình bằng cách sử dụng biến $ XDG_RUNTIME_DIR đã giữ đúng thư mục cho mỗi người dùng. Để biết thêm thông tin, hãy kiểm tra, ví dụ câu trả lời này: unix.stackexchange.com/questions/162900/ mẹo
Alex

1
Sử dụng mkstemp trên mktemp !! Lý do từ: linux.die.net/man/3/mktemp : trong phần Bugs "... mỗi lần sử dụng mktemp () là một rủi ro bảo mật, Cuộc đua được tránh bởi mkstemp (3)."
Alex

0

Theo tôi được biết, mục tiêu là: (1) làm lưu trữ các tập tin đảo ngược vào đĩa, để được phục vụ cho trình duyệt (lưu ý: đây có thể là tmpfs, vv, như tất cả các câu trả lời khác đã chi tiết); nhưng, (2) tránh ghi tệp tmp đầu tiên vào đĩa, với đầu ra ban đầu; tuy nhiên, (3) vẫn hiển thị đầu ra ban đầu thành thiết bị xuất chuẩn.

Nếu vậy, sau đây có thể đáp ứng nhu cầu của bạn, sử dụng thay thế quy trình bash (nghĩa là về cơ bản là một đường ống có tên):

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

Lưu ý rằng đây là liên tục in đầu ra thành thiết bị xuất chuẩn và khi lệnh kết thúc (khi vòng lặp của bạn kết thúc), đảo ngược đầu ra đó và ghi nó vào tệp đầu ra. Minh họa thông qua các mục sau, in một dòng mỗi giây và sau khi chấm dứt tệp /tmp/foo.txtchứa các dòng đảo ngược:

i=0
while [ $i -lt 10 ]; do
    ((i = i+1))
    echo "==$i== $(date)"
    sleep 1
done | tee >( tac >> /tmp/foo.txt ) 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.