शेल स्क्रिप्ट mktemp, अस्थायी नामित पाइप बनाने के लिए सबसे अच्छी विधि क्या है?


30

मैं अस्थायी फ़ाइलों के साथ बनाने के लिए इसके सबसे अच्छे रूप में अवगत हूं mktemp, लेकिन नामित पाइप के बारे में क्या?

मैं चीजों को यथासंभव POSIX के अनुरूप होना पसंद करता हूं, लेकिन लिनक्स केवल स्वीकार्य है। बाशिन्दों से बचना मेरा एकमात्र कठिन मापदंड है, जैसा कि मैं लिखता हूं dash

जवाबों:


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

नियमित फ़ाइल निर्माण के विपरीत, जो एक मौजूदा फ़ाइल या एक प्रतीकात्मक लिंक द्वारा अपहरण किए जाने के लिए प्रवण होता है, नाम फ़ंक्शन पाइप के माध्यम से mkfifoया अंतर्निहित फ़ंक्शन या तो निर्दिष्ट स्थान में एक नई फ़ाइल बनाता है या विफल रहता है। कुछ : >fooऐसा असुरक्षित है क्योंकि यदि हमलावर उत्पादन के बारे में अनुमान लगा सकता है mktempतो हमलावर अपने लिए लक्ष्य फ़ाइल बना सकता है। लेकिन mkfifo fooऐसे परिदृश्य में विफल होगा।

यदि आपको पूर्ण POSIX पोर्टेबिलिटी की आवश्यकता है, mkfifo -m 600 /tmp/myfifoतो अपहरण के खिलाफ सुरक्षित है, लेकिन सेवा से इनकार करने की संभावना है; एक मजबूत यादृच्छिक फ़ाइल नाम जनरेटर तक पहुंच के बिना, आपको रिट्री प्रयासों का प्रबंधन करने की आवश्यकता होगी।

यदि आप अस्थायी फ़ाइलों के आसपास सूक्ष्म सुरक्षा समस्याओं की परवाह नहीं करते हैं, तो आप एक सरल नियम का पालन कर सकते हैं: एक निजी निर्देशिका बनाएं, और वहां सब कुछ रखें।

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"

मैंने वास्तव में इसे पहले ही अपने समाधान के रूप में चुना था कल, मैं इंतजार कर रहा था कि कोई इसे पोस्ट करे, या एक बेहतर। मैंने भी महसूस किया कि डायर जाने का रास्ता था, मेरे मामले में। भले ही ... मदद के लिए धन्यवाद, मैं इसकी सराहना करता हूं।
जेएम बेकर

1
क्या ट्रैप कमांड नहीं होना चाहिए trap "rm -rf '$tempdir'" EXIT HUP INT TERM? क्या यह स्वयं का चर विस्तार कर सकता है?
छह

@ सिक्स आपकी कमांड का मूल्यांकन $tempdirउस समय होगा जब trapकमांड का मूल्यांकन किया जाता है, न कि उस समय ट्रैप को ट्रिगर किया जाता है। इस मामले में, इससे कोई फर्क नहीं पड़ता, सिवाय इसके कि अगर आपका कोड tempdirएक ही उद्धरण में है, तो आपका कोड बुरी तरह टूट जाता है , जबकि मेरा कोड हमेशा काम करता है।
गिल्स एसओ- बुराई को रोकें '

@ गिल्स यह एक अच्छी सुविधा है। मैंने भाग्य के बिना आपके एकल उद्धरण उदाहरण की कोशिश की थी, इसलिए मैंने सोचा कि जाल रनवे पर चर का मूल्यांकन करने में असमर्थ था। यह पता चला कि मेरा $tempdirस्थानीय रूप से घोषित किया गया था और जाल तक पहुँचने के लिए इसे विश्व स्तर पर परिभाषित किया जाना चाहिए। अब समझ में आता है ...
छह

1
@ गिल्स ... जब तक $tempdir मूल्य या तो बदल नहीं जाता है, जो मूल रूप से सभी उद्देश्यों के लिए स्वीकार्य है। बस एक ही नाम का उपयोग करने के लिए कई अस्थायी फ़ाइलों / dirs बनाने के लिए सावधान रहना होगा ...
MestreLion

3

सुरक्षित रूप से mktempएक निर्देशिका बनाने के लिए सुरक्षित विकल्प का उपयोग करना है, फिर उस निर्देशिका के अंदर अपना नामांकित पाइप डालें, rm -R $dirअंत में इसे से छुटकारा पाने के लिए करें।


मैंने एक mktempनिर्देशिका में FIFO बनाने का विकल्प चुना , क्योंकि यह वास्तव में एकमात्र स्वीकार्य उत्तर था, बस अगर आपने ध्यान नहीं दिया, तो @Gilles ने पहले ही इस उत्तर को गहराई से पोस्ट कर दिया।
जेएम बेकर

2

"ड्राई-रन" विकल्प का उपयोग करें:

mkfifo $(mktemp -ut pipe.XXX)

1
मैन पेज के अनुसार, -uविकल्प का उपयोग "प्रोत्साहित नहीं किया जाता है"।
dogbane 10

@ डोगबेन तो का उपयोग है -t, लेकिन जब तक यह मज़बूती से काम करता है, मैं इसके साथ जाऊंगा।
पोलीमोन

क्षमा करें, यह कहां कहता है कि -tहतोत्साहित किया जाता है।
कुत्ता पालना

2
@dogbane यदि यह किसी भी तरह से महत्वपूर्ण है, तो मैं mkstemp()फ़ंक्शन ( linux.die.net/man/3/mkstemp ) को कॉल करके एक छोटा सी एप्लिकेशन बनाऊंगा-tस्विच हतोत्साहित नहीं है, यह है -p, मेरा बुरा।
पोलीमोन

1

आप mktempएक अस्थायी फ़ाइल बनाने के लिए उपयोग कर सकते हैं , फिर उसे हटा सकते हैं और उसी नाम से एक नामांकित पाइप बना सकते हैं।

उदाहरण के लिए:

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

करने $TMPPIPEसे पहले mkfifo'असुरक्षित' समस्या से बचने के लिए हटाने से पहले करता है TMPPIPE=`mktemp -u` ; mkfifo $TMPPIPE?
जेएम बेकर

1
@TechZilla mkfifoवास्तव में शेल से सामान्य नियमित फ़ाइल निर्माण के विपरीत सुरक्षित है। यदि यह नहीं था, तो फ़ाइल बनाना, इसे हटाना बिल्कुल भी मदद नहीं करेगा (वास्तव में यह हमलावर की नौकरी की सुविधा प्रदान करेगा, जिससे उसे फ़ाइल नाम का अनुमान लगाने की आवश्यकता नहीं होगी)। तो डॉगबैन का जवाब काम करता है, लेकिन मध्यवर्ती फ़ाइल निर्माण एक बेकार जटिलता है।
गिल्स एसओ- बुराई को रोकना '

1
@ गिल्स, क्या आप जानते हैं कि mktempमैन पेज किस संबंध में -uविकल्प को 'असुरक्षित' कहते हैं?
जेएम बेकर

@dogbane, मैंने आपके जवाब पर मतदान किया, और आपकी टिप्पणी जो मुझे लगा कि ठोस थी। हालाँकि, मैंने पहले ही कल इसे पूरा कर लिया था .. मैं बस यह देखने के लिए इंतजार कर रहा था कि कब कोई मेरे समाधान को पोस्ट करे, या उम्मीद है कि एक बेहतर। इसलिए भले ही मैंने आपका उपयोग किया mktemp -dहो, फिर भी आपके इनपुट के लिए कुछ अंक मिले। आपकी सभी मदद के लिए धन्यवाद, मैं वास्तव में इसकी सराहना करता हूं!
जेएम बेकर

1
@TechZilla mktemp -uएक नियमित फ़ाइल बनाते समय असुरक्षित है, क्योंकि यह सेवा से वंचित करने से सुरक्षा प्रदान करता है (यदि यह नाम पर्याप्त रूप से उत्पन्न होता है) अप्रत्याशित है, लेकिन प्रोग्राम की नाक के नीचे एक हमलावर को फ़ाइल बनाने से नहीं रोकता है। एक नियमित फ़ाइल के बजाय एक फेनो बनाना एक दुर्लभ उपयोग मामला है जिसे मैन पेज संबोधित नहीं करता है।
गिलेस एसओ- बुराई को रोकना '

0

यूनिक्स में उपयोग करें mkfifoया करें mknod, जहां दो अलग-अलग प्रक्रियाएं पाइप को नाम से एक्सेस कर सकती हैं - एक प्रक्रिया इसे एक पाठक के रूप में और दूसरी एक लेखक के रूप में खोल सकती है।

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

नामित पाइप को किसी भी फाइल की तरह ही हटाया जा सकता है:

rm my_pipe

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

NamedPipe को केवल एक बार पढ़ने के लिए एक नियमित फ़ाइल का उपयोग किया जा सकता है।

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


2
मैं नामांकित पाइपों के बारे में पूरी तरह से अवगत हूं, और mkfifo। यह अस्थायी नाम वाले पाइपों के बारे में मेरे सवाल को संबोधित नहीं करता है , अब से mkdirअस्थायी निर्देशिकाओं को बनाने से पता चलेगा।
जेएम बेकर

2
यह उन मुद्दों को कैसे mktempसंबोधित करता है जो पते को सुरक्षित रूप से नामित पाइप बनाने के लिए कहते हैं ?
कैमह

1
ओह ठीक है, सबसे अच्छा है उन्हें / tmp के तहत बनाना, वे परिभाषा द्वारा अस्थायी फ़ाइलें हैं और सिस्टम रिबूट होने के बाद बंद कर देंगे। या बेहतर अभी तक, एक शेल फ़ंक्शन है जो mktempपरिणाम के नामपट्ट को स्वयं बना देगा (पहले अस्थायी फ़ाइल को हटाकर फिर mkfifoउसी पर चल रहा है )। mktempएक अस्थायी निर्देशिका बनाने के लिए भी इस्तेमाल किया जा सकता है, -t -dस्विच के साथ प्रयास करें।
निखिल मुले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.