2012-06-11 8 views
111

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

मैं सामान्य रूप से उनको नाम देता हूं जो मेरे दिमाग में आता है, जैसे tempfile-123, क्योंकि स्क्रिप्ट खत्म होने पर इसे हटा दिया जाएगा। वर्तमान फ़ोल्डर में संभावित टेम्पफाइल-123 को ओवरराइट करने के अलावा ऐसा करने में कोई नुकसान है? या एक अस्थायी फ़ाइल को अधिक सावधानीपूर्वक तरीके से बनाने में कोई फायदा है?

+0

अस्थायी रूप से फ़ाइलों का उपयोग न करें। इसके बजाए अस्थायी रूप से निर्देशिका का प्रयोग करें। और mktemp का उपयोग न करें। यहां देखें क्यों: http://www.codeproject.com/Articles/15956/ सुरक्षा- टिप्स-for- समकालीन- फ़ाइल- उपयोग-in- आवेदन – ceving

+14

@ceving यह आलेख बस गलत है, कम से कम जब शेल कमांड पर लागू होता है mktemp (mktemp लाइब्रेरी कॉल के विपरीत)। चूंकि mktemp फ़ाइल को एक प्रतिबंधक उमास्क के साथ बनाता है, हमलावर केवल तभी काम करता है जब हमलावर हमलावर के समान खाते के तहत काम कर रहा हो ... जिस स्थिति में गेम पहले से ही खो गया है। शेल-स्क्रिप्टिंग दुनिया में सर्वोत्तम प्रथाओं के लिए, http://mywiki.wooledge.org/BashFAQ/062 –

+0

देखें, आप सिस्टम पर 'tempfile (1)' का भी उपयोग कर सकते हैं। –

उत्तर

135

mktemp(1) आदमी पेज यह काफी अच्छी तरह से बताते हैं::

परंपरागत रूप से, कई शेल स्क्रिप्ट प्रोग्राम का नाम साथ पीआईडी ​​एक प्रत्यय और उपयोग के रूप में लेने के लिए ऐसा नहीं है कि फ़ाइल का नाम आउटपुट एक अस्थायी फ़ाइल नाम के रूप में। नामकरण योजना के इस प्रकार अनुमानित है और यह दौड़ने की दौड़ की स्थिति है जो हमलावर के लिए जीतने में आसान है। एक सुरक्षित, हालांकि अभी भी कम, दृष्टिकोण एक ही नामकरण योजना का उपयोग कर अस्थायी निर्देशिका बनाना है। जबकि यह किसी को यह गारंटी देने की अनुमति देता है कि एक अस्थायी फ़ाइल नहीं बदली जाएगी, यह अभी भी सेवा हमले की सरल अस्वीकार करने की अनुमति देती है। के लिए इन कारणों से यह सुझाव दिया जाता है कि इसके बजाय mktemp का उपयोग किया जाए।

एक स्क्रिप्ट में, मैं की तरह

mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX") 

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

mktemp मानक नहीं है, लेकिन यह कई प्लेटफ़ॉर्म पर मौजूद है। "एक्स" आमतौर पर कुछ यादृच्छिकता में परिवर्तित हो जाएगा, और शायद अधिक यादृच्छिक होगा; हालांकि, कुछ सिस्टम (बिजीबॉक्स राख, एक के लिए) दूसरों की तुलना में अधिक महत्वपूर्ण इस अनियमितता की सीमा


वैसे, अस्थायी फ़ाइलों की सुरक्षित निर्माण अधिक के लिए महत्वपूर्ण है की तुलना में सिर्फ पटकथा शैल।यही कारण है कि अजगर tempfile है पर्ल File::Temp है है,, माणिक Tempfile है, आदि ...

+1

-t विकल्प को बहिष्कृत किया गया है: http://www.gnu.org/software/coreutils/manual/html_node/mktemp-invocation.html –

+1

@TeaBee ओएस एक्स पर नहीं है – kojiro

+6

यह सबसे सुरक्षित और सबसे पार-प्लेटफ़ॉर्म लगता है 'mktemp' का उपयोग करने का तरीका 'बेसनाम' के साथ संयोजन में है, जैसे 'mktemp -dt" $ (बेसनाम $ 0)। XXXXXXXXXX "'। यदि 'बेसनाम' के बिना उपयोग किया जाता है तो आपको इस तरह की त्रुटि मिल सकती है जैसे _mktemp: अवैध टेम्पलेट, '/tmp/MOB-SAN-JOB1-183-ScriptBuildTask-7300464891856663368.sh.XXXXXXXXXX ', निर्देशिका विभाजक_ है। – i4niac

15

आप mktemp

को देखने के लिए mktemp उपयोगिता चाहते हो सकता है दी फ़ाइल नाम टेम्पलेट लेता है और एक अद्वितीय फ़ाइल नाम बनाने के लिए इसके बारे में एक भाग अधिलेखित कर देता है। टेम्पलेट फ़ाइल नाम हो सकता है जिसमें कुछ 'एक्स' शामिल हैं, उदाहरण के लिए /tmp/tfile.XXXXXXXXXX। पीछे की ओर 'एक्स' को वर्तमान प्रक्रिया संख्या और यादृच्छिक अक्षरों के संयोजन के साथ बदल दिया गया है।

अधिक जानकारी के लिए: man mktemp

26

हाँ, mktemp का उपयोग करें।

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

> mktemp 
/tmp/tmp.xx4mM3ePQY 
> 
9

वहाँ एक और अधिक सावधान रास्ता

अस्थायी फ़ाइलों को आम तौर पर तैयार किये जाते हैं में एक अस्थायी फ़ाइल बनाने में किसी भी लाभ है अस्थायी निर्देशिका (जैसे /tmp) जहां अन्य सभी उपयोगकर्ताओं और प्रक्रियाओं ने पहुंच को पढ़ और लिख लिया है (कोई अन्य स्क्रिप्ट वहां नई फाइलें बना सकती है)। इसलिए स्क्रिप्ट को सही अनुमतियों के साथ उपयोग करने जैसी फ़ाइलों को बनाने के बारे में सावधान रहना चाहिए (उदाहरण के लिए केवल स्वामी के लिए पढ़ें, देखें: help umask) और फ़ाइल नाम आसानी से अनुमानित नहीं किया जाना चाहिए (आदर्श रूप से यादृच्छिक)। अन्यथा यदि फ़ाइल नाम अद्वितीय नहीं हैं, तो यह एक ही स्क्रिप्ट के साथ कई बार दौड़ सकता है (उदाहरण के लिए race condition) या कुछ हमलावर या तो कुछ संवेदनशील जानकारी को हाइजैक कर सकते हैं (उदाहरण के लिए जब अनुमतियां खुली होती हैं और फ़ाइल नाम अनुमान लगाना आसान होता है) या/फ़ाइल को कोड के अपने संस्करण के साथ बदलना (जैसे संग्रहीत किए जा रहे कार्यों के आधार पर आदेश या SQL क्वेरी को प्रतिस्थापित करना)।


आप अस्थायी निर्देशिका बनाने में निम्नलिखित दृष्टिकोण इस्तेमाल कर सकते हैं:

TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR" 

या अस्थायी फ़ाइल:

TMPFILE=".${0##*/}-$$" && touch "$TMPFILE" 

हालांकि यह अभी भी उम्मीद के मुताबिक और सुरक्षित माना जाता नहीं है।

प्रति man mktemp रूप में, हम पढ़ सकते हैं:

परंपरागत रूप से, कई शेल स्क्रिप्ट एक प्रत्यय के रूप में पीआईडी ​​के साथ प्रोग्राम का नाम लेने के लिए और है कि एक अस्थायी फ़ाइल नाम के रूप में इस्तेमाल करते हैं। इस तरह की नामकरण योजना अनुमानित है और जिस दौड़ की स्थिति बनाता है वह हमलावर के लिए जीतना आसान है।

तो यह सुरक्षित है, यह mktemp आदेश का उपयोग करने के लिए अद्वितीय अस्थायी फ़ाइल या निर्देशिका (-d) बनाने के लिए सिफारिश की है।

+2

बिल्कुल नहीं पूछा गया था। फिर भी, यह एक आदर्श समाधान हो सकता है। – jpbochi

+1

@jpbochi मैंने प्रश्न का समाधान करने के लिए उत्तर में सुधार किया है। यदि इससे सहायता मिलती है तो मुझे बताएं। – kenorb

+0

यह वास्तव में उत्तर में सुधार करता है। मेरा उपरोक्त पहले से ही तुम्हारा था, हालांकि। अधिक वोट नहीं दे सकता। मेरे पास एक सुझाव है कि '$ {0 ## * /} 'और' $$ 'विस्तारित करें, या इसके बारे में कुछ दस्तावेज़ों से लिंक करें। – jpbochi