Shell Script mktemp, phương pháp tốt nhất để tạo đường ống có tên tạm thời là gì?


30

Tôi biết cách tốt nhất để tạo các tệp tạm thời mktemp, nhưng còn các ống có tên thì sao?

Tôi thích mọi thứ phải tuân thủ POSIX nhất có thể, nhưng chỉ Linux mới được chấp nhận. Tránh Bashism là tiêu chí khó khăn duy nhất của tôi, khi tôi viết dash.

Câu trả lời:


41
tmppipe=$(mktemp -u)
mkfifo -m 600 "$tmppipe"

Không giống như tạo tệp thông thường, dễ bị tấn công bởi một tệp hiện có hoặc một liên kết tượng trưng, ​​việc tạo một ống tên thông qua mkfifohoặc chức năng cơ bản tạo ra một tệp mới ở vị trí đã chỉ định hoặc thất bại. Một cái gì đó giống như : >foolà không an toàn bởi vì nếu kẻ tấn công có thể dự đoán đầu ra mktempthì kẻ tấn công có thể tự tạo tệp đích. Nhưng mkfifo foosẽ thất bại trong một kịch bản như vậy.

Nếu bạn cần tính di động POSIX đầy đủ, mkfifo -m 600 /tmp/myfifoan toàn chống lại việc chiếm quyền điều khiển nhưng dễ bị từ chối dịch vụ; không có quyền truy cập vào trình tạo tên tệp ngẫu nhiên mạnh, bạn sẽ cần quản lý các lần thử lại.

Nếu bạn không quan tâm đến các vấn đề bảo mật tinh vi xung quanh các tệp tạm thời, bạn có thể thực hiện theo một quy tắc đơn giản: tạo một thư mục riêng và giữ mọi thứ trong đó.

tmpdir=
cleanup () {
  if [ -n "$tmpdir" ] ; then rm -rf "$tmpdir"; fi
  if [ -n "$1" ]; then kill -$1 $$; fi
}
tmpdir=$(mktemp -d)
trap 'cleanup' EXIT
trap 'cleanup HUP' HUP
trap 'cleanup TERM' TERM
trap 'cleanup INT' INT
mkfifo "$tmpdir/pipe"

Tôi thực sự đã chọn đây là giải pháp của tôi trước đó vào ngày hôm qua, tôi đang chờ xem liệu ai đó đã đăng nó, hay một giải pháp tốt hơn. Tôi cũng cảm thấy dir là con đường để đi, trong trường hợp của tôi. Bất kể ... Cảm ơn vì sự giúp đỡ, tôi đánh giá cao nó.
JM Becker

1
Không nên lệnh bẫy trap "rm -rf '$tempdir'" EXIT HUP INT TERM? Bẫy có thể tự mở rộng biến?
Sáu

@Six Lệnh của bạn sẽ mở rộng $tempdirtại thời điểm traplệnh được ước tính, không phải tại thời điểm bẫy được kích hoạt. Trong trường hợp này, nó không tạo ra bất kỳ sự khác biệt nào, ngoại trừ việc mã của bạn bị hỏng khủng khiếp nếu giá trị tempdirchứa một trích dẫn, trong khi mã của tôi luôn hoạt động.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Đó là một tính năng hay. Tôi đã thử ví dụ trích dẫn duy nhất của bạn mà không gặp may mắn, vì vậy tôi nghĩ rằng bẫy không thể đánh giá các biến khi chạy. Hóa ra là của tôi $tempdirđã được tuyên bố tại địa phương và nó phải được xác định trên toàn cầu để bẫy có quyền truy cập vào nó. Làm cho ý nghĩa ngay bây giờ ...
Sáu

1
@Gilles ... miễn là $tempdir giá trị cũng không thay đổi, điều này có thể chấp nhận cho tất cả các mục đích. Chỉ cần cẩn thận không sử dụng cùng tên để tạo nhiều tệp / thư mục tạm thời ...
MestreLion

3

Một cách khác an toàn hơn là sử dụng mktempđể tạo một thư mục một cách an toàn, sau đó đặt đường ống có tên của bạn vào trong thư mục đó, thực hiện rm -R $dirđể loại bỏ nó cuối cùng.


Tôi đã chọn tạo FIFO trong một mktempthư mục, vì đó thực sự là câu trả lời duy nhất được chấp nhận, Chỉ trong trường hợp bạn không để ý, @Gilles đã đăng câu trả lời này một cách sâu sắc.
JM Becker

2

Sử dụng tùy chọn "chạy khô":

mkfifo $(mktemp -ut pipe.XXX)

1
Theo các trang nam, việc sử dụng -utùy chọn "không được khuyến khích".
dogbane

@dogbane Việc sử dụng cũng được -t, nhưng miễn là nó hoạt động đáng tin cậy, tôi sẽ sử dụng nó.
Polemon

xin lỗi, nó nói ở đâu mà -tnản lòng?
dogbane

2
@dogbane Nếu theo bất kỳ cách nào quan trọng, tôi sẽ tạo một ứng dụng C nhỏ, gọi mkstemp()hàm ( linux.die.net/man/3/mkstemp ). Công -ttắc không được khuyến khích, đó là -p, xấu của tôi.
Polemon

1

Bạn có thể sử dụng mktempđể tạo một tệp tạm thời, sau đó xóa nó và tạo một ống có tên cùng tên.

Ví dụ:

TMPPIPE=$(mktemp -t pipe.XXX) && {
    rm -f $TMPPIPE
    mkfifo $TMPPIPE
}

Việc xóa $TMPPIPEtrước khi mkfifotránh vấn đề 'không an toàn' liên quan đến việc thực hiện TMPPIPE=`mktemp -u` ; mkfifo $TMPPIPE?
JM Becker

1
@TechZilla mkfifothực sự an toàn, không giống như việc tạo tập tin thông thường từ trình bao. Nếu không, việc tạo một tệp sau đó xóa nó sẽ không giúp ích gì cả (thực tế nó sẽ tạo điều kiện thuận lợi cho công việc của kẻ tấn công bằng cách không yêu cầu anh ta đoán tên tệp). Vì vậy, câu trả lời của dogbane hoạt động, nhưng việc tạo tập tin trung gian là một sự phức tạp vô dụng.
Gilles 'SO- ngừng trở nên xấu xa'

1
@Gilles, Bạn có biết mktemptrang nào được gọi là -utùy chọn 'không an toàn' không?
JM Becker

@dogbane, tôi đã bỏ phiếu cho câu trả lời của bạn, và ý kiến ​​của bạn mà tôi cảm thấy là vững chắc. Mặc dù, tôi đã hoàn thành việc này ngày hôm qua .. Tôi chỉ chờ đợi khi ai đó đăng giải pháp của tôi, hoặc hy vọng một giải pháp tốt hơn. Vì vậy, mặc dù tôi đã sử dụng mktemp -dbạn vẫn có một số điểm cho đầu vào của bạn. Cảm ơn tất cả sự giúp đỡ của bạn, tôi thực sự đánh giá cao nó!
JM Becker

1
@TechZilla mktemp -ukhông an toàn khi tạo một tệp thông thường, bởi vì nó cung cấp sự bảo vệ chống lại sự từ chối dịch vụ (nếu tên mà nó tạo ra đủ khó đoán) nhưng không ngăn kẻ tấn công tạo tệp dưới mũi chương trình. Tạo một fifo thay vì một tệp thông thường là trường hợp sử dụng hiếm hoi mà trang man không giải quyết.
Gilles 'SO- ngừng trở nên xấu xa'

0

Sử dụng mkfifohoặc mknodtrong Unix, trong đó hai quy trình riêng biệt có thể truy cập vào đường ống theo tên - một quy trình có thể mở nó dưới dạng trình đọc và quy trình còn lại là nhà văn.

mkfifo my_pipe
gzip -9 -c < my_pipe > out.gz
cat file > my_pipe

Ống có tên có thể bị xóa giống như bất kỳ tập tin nào:

rm my_pipe

mkfifo --mode=0666 /tmp/namedPipe
gzip --stdout -d file.gz > /tmp/namedPipe

NamedPipe có thể được sử dụng một tệp thông thường để chỉ đọc một lần.

http://www.linuxjournal.com/article/2156


2
Tôi hoàn toàn biết về các đường ống được đặt tên, và mkfifo. Nó không giải quyết câu hỏi của tôi về các đường ống được đặt tên tạm thời , hơn là mkdirgiải quyết việc tạo các thư mục tạm thời.
JM Becker

2
Làm thế nào để giải quyết các vấn đề mktempgiải quyết một cách an toàn để tạo ra một đường ống có tên?
camh

1
oh ok, tốt nhất là tạo chúng dưới / tmp, chúng là các tệp tạm thời theo định nghĩa và sẽ xóa sau khi hệ thống khởi động lại. Hoặc tốt hơn nữa, có một hàm shell sẽ tạo ra tên được lấy ra khỏi mktempchính kết quả (dĩ nhiên bằng cách xóa tệp tạm thời trước rồi chạy mkfifotrên cùng). mktempcũng có thể được sử dụng để tạo một thư mục tạm thời, thử với -t -dchuyển đổi.
Nikhil Mulley
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.