2008-09-16 7 views
109

मैंने एक बार पढ़ा कि temp फ़ाइलों के लिए एक खोल में एक अद्वितीय फ़ाइल नाम प्राप्त करने का एक तरीका एक डबल डॉलर संकेत ($$) का उपयोग करना था। यह एक संख्या उत्पन्न करता है जो समय-समय पर भिन्न होता है ... लेकिन यदि आप इसे बार-बार कहते हैं, तो यह वही संख्या देता है। (समाधान केवल समय का उपयोग करना है।)

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

उत्तर

69

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

अस्थायी फ़ाइल नामों के लिए, mktemp कमांड का उपयोग करें।

+33

लोग हैं, जो सिर्फ शीर्ष जवाब को देखने के लिए, $$ भी एक एकल फाइल (उदा/tmp) एक सार्वजनिक रूप से लिखने योग्य निर्देशिका के लिए लिखने के लिए ठीक नहीं है। Symlinks के साथ कूड़े/tmp करना आसान है जो आपकी स्क्रिप्ट को कहीं अवांछित लिखने का कारण बनता है। mktemp बहुत बेहतर है। –

+4

हाँ, $$ का उपयोग करने से एक बुरा सुरक्षा छेद होगा। ऐसा मत करो – emk

+2

पर्याप्त प्रतिनिधि वाले किसी को उत्तर को संपादित करना चाहिए ... – dwestbrook

14

$$ वर्तमान प्रक्रिया की आईडी है।

2

$$ वर्तमान खोल प्रक्रिया का ढक्कन है। यह अद्वितीय फ़ाइल नाम उत्पन्न करने का एक अच्छा तरीका नहीं है।

1

यह बैश प्रक्रिया की प्रक्रिया आईडी है। कोई समवर्ती प्रक्रियाओं में कभी भी एक ही पीआईडी ​​नहीं होगी।

6

यूनिक्स में ऑपरेटिंग सिस्टम की तरह प्रत्येक प्रक्रिया में एक अस्थायी रूप से अद्वितीय पहचानकर्ता, पीआईडी ​​होता है। एक ही समय में चलने वाली दो प्रक्रियाओं में एक ही पीआईडी ​​हो सकती है, और $$ स्क्रिप्ट चलाने वाले बैश इंस्टेंस के पीआईडी ​​को संदर्भित करता है।

यह बहुत अधिक एक अनूठा आइडेंटिफायर इस अर्थ में है कि इसका पुन: उपयोग नहीं किया जाएगा (वास्तव में, पीआईडी ​​लगातार उपयोग किया जाता है)। यह आपको एक संख्या देता है जैसे कि, यदि कोई अन्य व्यक्ति आपकी स्क्रिप्ट चलाता है, तो आपका एक अलग पहचानकर्ता होगा जबकि आपका अभी भी चल रहा है। एक बार तुम्हारी मृत्यु हो जाने के बाद, पीआईडी ​​का पुनर्नवीनीकरण किया जा सकता है और कोई और आपकी स्क्रिप्ट चला सकता है, एक ही पीआईडी ​​प्राप्त कर सकता है, और इसलिए एक ही फ़ाइल नाम प्राप्त करें।

इस प्रकार, यह केवल सचमुच कहने के लिए है कि "$$ एक फ़ाइल नाम देता है जैसे कि अगर कोई और एक ही स्क्रिप्ट चलाता है तो मेरा उदाहरण अभी भी चल रहा है, उन्हें एक अलग नाम मिलेगा"।

1

$$ उस शेल की प्रक्रिया आईडी है जिसमें आपकी स्क्रिप्ट चल रही है। अधिक जानकारी के लिए, sh या bash के लिए मैन पेज देखें। मैन पेज या तो कमांड लाइन "मैन श" का उपयोग करके या "शैल मैनपेज"

4

$$ के लिए वेब खोजकर पाया जा सकता है। यह वास्तव में एक अद्वितीय फ़ाइल नाम उत्पन्न नहीं करता है, जब तक कि आप सावधान न हों और कोई भी वही तरीके से ऐसा नहीं करता है।

आमतौर पर आप की तरह/tmp/myprogramname $$ कुछ बनाना चाहते हैं

इस तोड़ने के लिए कई मायनों कर रहे हैं, और अन्य लोगों आप स्थानों के लिए लिख रहे हैं करने के लिए यह कई पर भी मुश्किल नहीं है लिख सकते हैं ओएसई भविष्यवाणी करने के लिए कि आप किस पीआईडी ​​के पास जा रहे हैं और चारों ओर पेंच कर रहे हैं - कल्पना करें कि आप रूट के रूप में चल रहे हैं और मैं/etc/passwd को इंगित करने वाले सिम्लिंक के रूप में/tmp/yourprogname13395 बना देता हूं - और आप इसमें लिखते हैं।

शैल स्क्रिप्ट में ऐसा करना एक बुरी बात है। यदि आप किसी चीज़ के लिए अस्थायी फ़ाइल का उपयोग करने जा रहे हैं, तो आपको एक बेहतर भाषा का उपयोग करना चाहिए जो कम से कम आपको फाइल को खोलने (बनाने) के लिए "अनन्य" ध्वज जोड़ देगा। फिर आप सुनिश्चित हो सकते हैं कि आप कुछ और नहीं कर रहे हैं।

1

$$ आपकी स्क्रिप्ट चलाने वाले शेल दुभाषिया की पिड (प्रक्रिया आईडी) है। इस समय सिस्टम पर चलने वाली प्रत्येक प्रक्रिया के लिए यह अलग है, लेकिन समय के साथ ही पिड चारों ओर लपेटता है, और बाहर निकलने के बाद अंततः एक ही प्रक्रिया के साथ एक और प्रक्रिया होगी।जब तक आप चल रहे हैं, तब तक पिड आपके लिए अद्वितीय है।

उपर्युक्त परिभाषा से यह स्पष्ट होना चाहिए कि इससे कोई फर्क नहीं पड़ता कि आप एक स्क्रिप्ट में $$ का कितनी बार उपयोग करते हैं, यह वही संख्या वापस कर देगा।

आप इसका उपयोग कर सकते हैं, उदा। /tmp/myscript.scratch.$$ उन चीज़ों के लिए अपनी temp फ़ाइल के रूप में जिन्हें अत्यधिक विश्वसनीय या सुरक्षित नहीं होना चाहिए। यह अपनी स्क्रिप्ट के अंत में इस तरह के अस्थायी फ़ाइलों को हटाने के लिए एक अच्छा अभ्यास है, का उपयोग करते हुए उदाहरण के लिए है, जाल आदेश:

trap "echo 'Cleanup in progress'; rm -r $TMP_DIR" EXIT 
91

$$ प्रक्रिया ID (पीआईडी) बैश में है। $$ का उपयोग करना एक बुरा विचार है, क्योंकि यह आम तौर पर दौड़ की स्थिति बना देगा, और आपके शेल-स्क्रिप्ट को हमलावर द्वारा प्रतिस्थापित करने की अनुमति देगा। उदाहरण के लिए, सभी these people देखें, जिन्होंने असुरक्षित अस्थायी फ़ाइलों को बनाया और सुरक्षा सलाह जारी करना पड़ा।

इसके बजाय, mktemp का उपयोग करें। Linux man page for mktemp उत्कृष्ट है। यहाँ यह से कुछ उदाहरण कोड है:

tempfoo=`basename $0` 
TMPFILE=`mktemp -t ${tempfoo}` || exit 1 
echo "program output" >> $TMPFILE 
+3

धन्यवाद। 'Mktemp' विकल्प' -t' अब बहिष्कृत है (मुझे लगता है कि char '-' के साथ समस्याएं हैं)। ** इन दिनों ** mktemp $ {tempfoo} .XXXXXX' का उपयोग करें **। मैं आपकी पोस्ट को अपडेट करने की स्वतंत्रता लेता हूं। – Sebastian

+0

कृपया यह भी ध्यान दें कि [बैकटिक बहिष्कृत किया गया था] (http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html#tag_23_02_06_03), इसलिए इसके बजाय 'TMPFILE = $ (mktemp) 'का उपयोग करें। –

1

मुझे दूसरा EMK का जवाब दें - एक "अद्वितीय" कुछ भी रूप में अपने आप में $$ का उपयोग नहीं करते। फ़ाइलों के लिए, mktemp का उपयोग करें। एक ही बैश स्क्रिप्ट के भीतर अन्य आईडी के लिए, उचित रूप से विशिष्टता के अच्छे अवसर के लिए "$$$ (दिनांक +% s% N)" का उपयोग करें।

-k 
0

इसके अलावा, आप इस आदेश के माध्यम से लॉगिन उपयोगकर्ता नाम हड़पने कर सकते हैं। उदाहरण के लिए।

echo $(</proc/$$/login id). After that, you need to use getent command.