OS X में mktemp के लिए फिक्स या वैकल्पिक


72

मैं एक बैश स्क्रिप्ट देख रहा हूँ जो किसी और ने लिखी है जो उपयोग करता है mktemp:

TEMP=`mktemp --directory`

हालाँकि, यह लाइन मेरी मशीन (OS X 10.6) पर काम नहीं करती है।

मैं इस लाइन को कैसे ठीक करूंगा ताकि यह क्रॉस-अन * एक्स-जैसा-प्लेटफॉर्म संगत हो? संपादित करें: एक वैकल्पिक आदेश पर्याप्त होगा।

जवाबों:


108

निम्नलिखित वह है जो मैंने अस्थायी रूप से एक अस्थायी निर्देशिका बनाने के लिए उपयोग किया था जो लिनक्स और डार्विन (मैक ओएस एक्स 10.11 से पहले सभी संस्करण) पर काम करता है, बिना हार्डकोड $TMPDIRया /tmp:

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`

पृष्ठभूमि:

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

सादा mktemp -dफ़ाइल के बजाय एक निर्देशिका बनाएगा, जो आप लिनक्स पर उपयोग करना चाहते हैं।

(gnu-coreutils)$ man mktemp
> ..
> If DIR is not specified, uses $TMPDIR if set, else /tmp.
> ..

डिफ़ॉल्ट रूप से, GNU mktemp tmp.XXXXXXXXXXउप निर्देशिका (या फ़ाइल) के नाम के लिए टेम्पलेट का उपयोग करता है । इस टेम्पलेट को कस्टमाइज़ करने के लिए, -tविकल्प का उपयोग किया जा सकता है।

OSX के mktemp का कोई डिफ़ॉल्ट टेम्पलेट नहीं है और इसे निर्दिष्ट करने के लिए टेम्पलेट की आवश्यकता होती है। दुर्भाग्य से, जहां GNU mktemp टेम्पलेट के रूप में -tविकल्प लेता है , OSX पर यह स्थितिगत तर्क के रूप में पारित किया जाता है। इसके बजाय, OSX के mktemp में एक -tविकल्प है जिसका अर्थ कुछ और है। -tपर OSX विकल्प टेम्पलेट के लिए एक "उपसर्ग" के रूप में दर्ज है। इसका विस्तार किया जाता है {prefix}.XXXXXXXX, इसलिए यह X को अपने आप जोड़ता है (उदाहरण के लिए अस्थायी निर्देशिका में mktemp -d -t exampleबना सकता है example.zEJZWCTQ)।

मैं खोजने के लिए कई लिनक्स वातावरण में, कि आश्चर्य हुआ $TMPDIRहै नहीं डिफ़ॉल्ट रूप से निर्धारित किया है। कई CLI प्रोग्राम सेट होने पर इसका समर्थन करते हैं, लेकिन फिर भी इसके लिए डिफ़ॉल्ट की आवश्यकता होती है /tmp। इसका मतलब है $TMPDIR/example.XXXXXXXXकि mktemp या mkdir को पारित करना खतरनाक है क्योंकि यह /example.XXXXXXXXस्थानीय डिस्क की रूट डायरेक्टरी में उत्पन्न हो सकता है ($ TMPDIR के बिना परेशान होने और खाली स्ट्रिंग बनने के कारण)।

OSX पर, $TMPDIRहमेशा सेट किया जाता है और (कम से कम डिफ़ॉल्ट शेल में) यह सेट नहीं किया जाता है /tmp(जो कि एक सिम्लिंक है /private/tmp) लेकिन करने के लिए /var/folders/dx/*****_*************/T। इसलिए हम OSX के लिए जो कुछ भी करते हैं, उस डिफ़ॉल्ट व्यवहार का सम्मान करना चाहिए।

अंत में, निम्नलिखित वह है जो मैंने अस्थायी रूप से एक अस्थायी निर्देशिका बनाने के लिए उपयोग किया था जो लिनक्स या डार्विन (मैक ओएस एक्स) दोनों पर काम करता है , बिना हार्डकॉडिंग $TMPDIRया /tmp:

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`

पहला भाग लिनक्स के लिए है। यह कमांड डार्विन (Mac OS X) पर 1" स्टेटस : ..." के साथ एरर स्टेटस कोड के साथ फेल होगा । इसलिए हम stderr को नजरअंदाज करते हैं और इसके बजाय Mac वेरिएंट को निष्पादित करते हैं। mytmpdirउपसर्ग केवल मैक (जहां उस विकल्प को सेट करने के लिए आवश्यक है) पर प्रयोग किया जाता है।


12
बहुत कूल। कभी-कभी OS X अलग व्यवहार कष्टप्रद होता है।
therealmarv

6
@ एथिल्मार्व मैं हमेशा कहूंगा, हमेशा।
निकिता वोल्कोव

10
मैं बस mktemp -dOS X 10.11.5 El Capitan पर भागा , और इसने उम्मीद के मुताबिक काम किया file $(mktemp -d): /var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
हीथ बॉर्डर्स

2
हां। मुझे आश्चर्य हुआ क्योंकि आप यह काम कर रहे थे।
हीथ बॉर्डर्स

1
यदि आप mktemp -d -t 'mytmpdir'लिनक्स पर चलते हैं (साथ mktempसे परीक्षण किया गया है coreutils 8.26), तो यह अपेक्षित रूप से काम करता है।

15

आपको एक टेम्पलेट की आपूर्ति करनी होगी। mktemp -d /tmp/foo.XXXXकार्य करना चाहिए। मैंने कभी नहीं देखा --directory। यह --बताता है कि यह एक GNU एक्सटेंशन है।


6
यदि आप $TMPDIRउपलब्ध होने पर उपयोग करना चाहते हैं , तो करें mktemp -d "${TMPDIR:-/tmp}"/foo.XXXX। यह मैक पर बैश और डेबियन पर डैश का काम करता है, इसलिए यह पोर्टेबल लगता है।
टॉम एंडरसन

9

बदले --directoryके लिए -d। पूर्व एक GNU-ism है, लेकिन कोरुटिल्स mktempसे GNU भी समर्थन करता है -dmktempओएस एक्स में बीएसडी से के रूप में ही है, इसलिए -dप्रणाली है कि वास्तव में एक जहाज के बीच बहुत पोर्टेबल होना चाहिए mktempकार्यक्रम।


मैंने बस कोशिश की mktemp -d, और यह भी काम नहीं करता है।
दिमाग।

1
काइल का पूरा जवाब है। mktempओएस एक्स पर एक टेम्पलेट की आवश्यकता है। वह स्क्रिप्ट जो आप GNU सम्मेलनों का उपयोग कर रहे हैं, यदि कोई आपूर्ति नहीं की जाती है तो डिफ़ॉल्ट टेम्पलेट का उपयोग करता है।
जेम्स स्नेनर

समस्या यह है कि यूनिक्स XXXXXटेम्पलेट में आपूर्ति होने की उम्मीद करता है जहां ओएस एक्स सुनिश्चित नहीं होता है कि क्या कोई संगत टेम्पलेट ध्वज है?
user3467349

2
mktempOS X 10.11.5 पर El Capitan मेरे लिए काम करता है file $(mktemp -d):/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
Heath बॉर्डर्स

4
temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX")"
  • mktempबीएसडी के लिए ( ओएसएक्स सहित ) को एक टेम्पलेट की आवश्यकता होती है, लेकिन यह टेम्पलेट में किसी भी संख्या की अनुमति देता है X
  • (GNU) mktempलिनक्स के लिए किसी टेम्पलेट की आवश्यकता नहीं होती है, हालाँकि, यदि कोई टेम्पलेट निर्दिष्ट किया जाता है, तो s की संख्या X6 होनी चाहिए।

ध्यान दें कि GNU के-t लिए पदावनत किया जाता हैmktemp , इसलिए भविष्य में अधिक प्रमाण वाला कोड होगा

temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX" 2>/dev/null || mktemp -q -d)"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.