Làm thế nào để tự động xóa một thư mục khi thực thi bị giết


9

Rất thường xuyên, chúng tôi chạy một tệp thực thi cần ghi / đọc một số tệp tạm thời. Chúng tôi thường tạo một thư mục tạm thời, chạy tệp thực thi ở đó và xóa thư mục khi tập lệnh được hoàn thành.

Tôi muốn xóa thư mục ngay cả khi thực thi bị giết. Tôi đã cố gắng bọc nó vào:

#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
/usr/local/bin/my_binary

Khi my_binarychết, tiến trình cuối cùng kernel sẽ xóa thư mục, vì script là tiến trình cuối cùng giữ điều đó inode; nhưng tôi không thể tạo bất kỳ tập tin nào trong thư mục đã xóa.

#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
touch file.txt

đầu ra touch: file.txt: No such file or directory

Điều tốt nhất tôi có thể đưa ra là xóa thư mục tạm thời khi quá trình chết, bắt các tín hiệu phổ biến nhất và chạy quy trình dọn dẹp với cron:

#!/bin/bash
dir=$(mktemp -d /tmp/d.XXXXXX) && cd "$dir" || exit 99
trap 'rm -rf "$dir"' EXIT
/usr/local/bin/my_binary

Có một số cách đơn giản để tạo một thư mục thực sự tạm thời sẽ tự động bị xóa khi nhị phân hiện tại chết, không có vấn đề gì?


1
hãy cẩn thận rằng bạn có một cửa sổ nhỏ nơi cleanupcó thể được thực thi trước khi thực hiện mktemp. Bạn có thể muốn unset dirtrước khi đặt bẫy.
Stéphane Chazelas

Bắt tốt, tôi đã cập nhật tập lệnh để xử lý việc này và xử lý lỗi trong mktemp.
Joaquin Cuenca Abela

Tôi nghĩ rằng lối ra là bắt buộc. Đã sửa.
Joaquin Cuenca Abela

Ví dụ cuối cùng của bạn đề cập đến cron, nhưng không liên quan gì đến cron. Đó là ví dụ cuối cùng cũng là an toàn thất bại nhất. Điều duy nhất nó sẽ không xử lý là SIGKILL.
Patrick

Tôi đã không bao gồm tập lệnh cron mà tôi đang chạy để giữ cho nó không thành công. Đó là một phát hiện trên mẫu đó để khớp với các thư mục cũ hơn 1 giờ và rm chúng. Tôi muốn biết nếu có bất kỳ giải pháp nào cũng sẽ bao gồm trường hợp sigkill, hoặc thậm chí là tắt máy tàn bạo ở giữa kịch bản.
Joaquin Cuenca Abela

Câu trả lời:


3

Ví dụ cuối cùng của bạn là an toàn thất bại nhất.

trap 'rm -rf "$dir"' EXIT

Điều này sẽ thực thi miễn là bản thân shell vẫn hoạt động. Về cơ bản SIGKILL là điều duy nhất mà nó sẽ không xử lý được vì lớp vỏ bị chấm dứt cưỡng bức.
(có lẽ SIGSEGV cũng vậy, đã không thử, nhưng nó có thể bị bắt)

Nếu bạn không để nó lên vỏ để tự dọn dẹp, thì cách duy nhất khác có thể là để nhân làm điều đó. Đây thường không phải là một tính năng kernel, tuy nhiên có một mẹo bạn có thể làm, nhưng nó có vấn đề riêng:

#!/bin/bash
mkdir /tmp/$$
mount -t tmpfs none /tmp/$$
cd /tmp/$$
umount -l /tmp/$$
rmdir /tmp/$$

do_stuff

Về cơ bản, bạn tạo ra một tmpfs mount, và sau đó lười biếng ngắt kết nối nó. Khi tập lệnh được hoàn thành, nó sẽ bị xóa.
Nhược điểm khác hơn là quá phức tạp, là nếu tập lệnh chết vì bất kỳ lý do nào trước khi kết thúc, bạn sẽ không có một giá trị đặt xung quanh.
Điều này cũng sử dụng tmpfs, sẽ tiêu thụ bộ nhớ. Nhưng bạn có thể làm cho quá trình phức tạp hơn và sử dụng hệ thống tệp vòng lặp và xóa tệp sao lưu sau khi được gắn.


Cuối cùng, điều traptốt nhất là sự đơn giản và an toàn, và trừ khi tập lệnh của bạn thường xuyên bị SIGKILLed, tôi sẽ gắn bó với nó.


Có vấn đề gì nếu cái bẫy được đặt trước mktemphoặc sau nó không? Tôi sẽ nghĩ nếu bẫy được đặt ngay trước mktemp, thì ngay cả khi tín hiệu thoát được nhận sau bẫy và trước đó mktemp, tất cả những gì sẽ xảy ra là một rm -rflệnh sẽ được chạy với một đối số trống, không thực hiện được gì. Nhưng nếu cái bẫy xuất hiện sau mktempđó, có thể có một cửa sổ nhỏ về cơ hội mà thư mục tạm thời sẽ bị bỏ lại. Hay tôi hoàn toàn rời khỏi căn cứ?
tự đại diện

1

Bạn có thể sử dụng chờ đợi BUILTIN chờ một công việc nền đến khi kết thúc:

blah &
wait
rm -rf $DIR

Nhưng điều đó sẽ tương đương với blah; rm -rf $DIR, phải không? Nó có vấn đề là nó sẽ rò rỉ $ DIR nếu tập lệnh bị giết.
Joaquin Cuenca Abela

Nếu tập lệnh con bị giết, tập lệnh cha vẫn sẽ ở xung quanh để dọn sạch sau tập lệnh đó. Nếu tập lệnh cha cũng bị giết, thì yeah, thư mục sẽ bị bỏ lại.
Matthew Cline
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.