बैश में अस्थायी फाइलें बनाना


150

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

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


1
अस्थायी रूप से फ़ाइलों का उपयोग न करें। इसके बजाय अस्थायी निर्देशिकाओं का उपयोग करें। और mktemp का उपयोग न करें। यहाँ देखें क्यों: codeproject.com/Articles/15956/…
छत

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

आप उन tempfile(1)प्रणालियों पर भी उपयोग कर सकते हैं जिनके पास यह है।
अगली सूचना तक रोक दिया गया।

जवाबों:


179

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

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

एक पटकथा में, मैं कुछ ऐसा ही मानता हूं

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

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

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


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



7
ऐसा लगता है उपयोग करने के लिए सबसे सुरक्षित और सबसे पार मंच तरीका mktempके साथ संयोजन में है basename, इसलिए की तरह mktemp -dt "$(basename $0). XXXXXXXXXX"। यदि basenameआपके बिना उपयोग किया जाता है, तो आपको इस mktemp जैसी त्रुटि मिल सकती है : अमान्य टेम्प्लेट, '/tmp/MOB-SAN-JOB1-183-ScriptBuildTask-7300464891856663368.sh.XXXXXXXXXXX'
i4niac

7
उन्हें टाइपो (अतिरिक्त स्थान) पर ध्यान न दें। mktemp -dt "$(basename $0).XXXXXXXXXX"सही तरीका है।
४-३६ सी २nia

3
@ i4niac: आपको यह उद्धृत करने की आवश्यकता है कि $0, OS X की भूमि में बहुत सारे स्थान हैं।mktemp -dt "$(basename "$0").XXXXXX"
Orwellophile

11
इसके अलावा स्क्रिप्ट निष्पादन के अंत में टेंपर्ड को हटाना अच्छा हो सकता है:trap "rm -rf $mydir" EXIT
कुम

43

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

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

> mktemp
/tmp/tmp.xx4mM3ePQY
>

19

आप देखना चाह सकते हैं mktemp

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

अधिक जानकारी के लिए: आदमी mktemp


11

क्या अधिक सावधानी से अस्थायी फ़ाइल बनाने में कोई लाभ है

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


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

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

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

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

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

के अनुसार man mktemp, हम पढ़ सकते हैं:

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

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


2
जैसा पूछा था वैसा नहीं। फिर भी, यह एक सही समाधान हो सकता है।
'23

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

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

0

mktemp शायद सबसे बहुमुखी है, खासकर यदि आप थोड़ी देर के लिए फ़ाइल के साथ काम करने की योजना बनाते हैं।

आप एक प्रक्रिया प्रतिस्थापन ऑपरेटर का उपयोग भी कर सकते हैं <()यदि आपको केवल किसी अन्य कमांड के इनपुट के रूप में अस्थायी रूप से फ़ाइल की आवश्यकता हो, जैसे:

$ diff <(echo hello world) <(echo foo bar)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.