जवाबों:
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
: ...
rm "$tmpfile"
आप यह सुनिश्चित कर सकते हैं कि जब स्क्रिप्ट से बाहर निकलता है (फाइल को मारता है और क्रैश करता है) तो फाइल डिस्क्रिप्टर को फाइल से हटाकर उसे हटा दिया जाता है। /proc/$PID/fd/$FD
जब तक फाइल डिस्क्रिप्टर खुला रहता है, तब तक फाइल उपलब्ध रहती है (स्क्रिप्ट के लिए; अन्य प्रक्रियाओं के लिए नहीं, बल्कि काम के इर्द-गिर्द)। जब यह बंद हो जाता है (जो प्रक्रिया समाप्त होने पर कर्नेल स्वचालित रूप से करता है) फ़ाइल सिस्टम फ़ाइल को हटा देता है।
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
exec 3>"$tmpfile"
rm "$tmpfile"
: ...
echo foo >&3
/proc
- सिवाय उन प्रणालियों को छोड़कर जिनके पास यह नहीं है।
exec 3> "$tmpfile"
है? क्या यह केवल उपयोगी नहीं है अगर tmpfile एक स्टैंड-अलोन स्क्रिप्ट है?
cat <&3
देंगे Bad file descriptor
। अगर आप इसे ठीक करते हैं या इसे हटाते हैं तो मैं इसकी सराहना करूंगा; गलत सूचना ज्यादा मदद नहीं करती है।
mktemp
एक अस्थायी फ़ाइल या निर्देशिका बनाने के लिए उपयोग करें :
temp_file=$(mktemp)
या एक डाइरकोट्री के लिए:
temp_dir=$(mktemp -d)
स्क्रिप्ट के अंत में आपको अस्थायी फ़ाइल को हटाना होगा:
rm ${temp_file}
rm -R ${temp_dir}
mktemp /tmp
निर्देशिका में या --tmpdir
तर्क के साथ दिए गए डॉक्यूमेंटरी में फ़ाइल बनाता है।
trap "rm -f $temp_file" 0 2 3 15
फ़ाइल बनाने के बाद सही उपयोग कर सकते हैं ताकि जब स्क्रिप्ट बाहर निकल जाए या ctrl-C
फ़ाइल के साथ रोका जाए तब भी हटा दिया जाए।
EXIT
केवल हुक के लिए है trap
?
kill -9 $somepid
। वह विशेष रूप से मार संकेत इंस्टा-मौत है और कुछ नहीं हो रहा है।
bash -c 'echo $$; trap "echo foo" 0; sleep 5'
EXIT
काफी है।
यदि आप सिस्टम पर हैं, जिसमें mktemp है , तो आपको इसे अन्य उत्तरों के रूप में उपयोग करना चाहिए।
POSIX उपकरण के साथ:
umask 0177
tmpfile=/tmp/"$0"."$$"."$(awk 'BEGIN {srand();printf "%d\n", rand() * 10^10}')"
trap 'rm -f -- "$tmpfile"' INT TERM HUP EXIT
: > "$tmpfile"
EXIT
केवल हुक के लिए क्या होता है trap
?
tmpfile
स्क्रिप्ट से बाहर निकलने से पहले ही हटा दिया जाना चाहिए, लेकिन तब नहीं जब स्क्रिप्ट को अन्य सिग्नल मिले।
That's not what happens
?
mktemp
एक अलग सिंटैक्स के साथ एचपी / यूएक्स में उत्पन्न हुआ। टॉड सी। मिलर ने 90 के दशक के मध्य में (FreeBSD और NetBSD द्वारा प्रतिलिपि) OpenBSD के लिए एक अलग बनाया और बाद में इसे स्टैंडअलोन उपयोगिता (www.mktemp.org) के रूप में भी उपलब्ध कराया। यह वह है जो आमतौर पर लिनक्स पर उपयोग किया जाता था जब तक कि (ज्यादातर संगत) mktemp
उपयोगिता को 2007 में जीएनयू कोर्यूटिल्स में जोड़ा गया था। बस कहने के लिए एक वास्तव में mktemp
जीएनयू उपयोगिता नहीं कह सकता है।
कुछ गोले में अंतर्निहित सुविधा है।
zsh
की =(...)
प्रक्रिया प्रतिस्थापन के रूप में एक अस्थायी फ़ाइल का उपयोग करता है। उदाहरण के लिए =(echo test)
एक अस्थायी फ़ाइल के पथ में विस्तार होता है, जिसमें सम्मिलित है test\n
।
$ {cat $file; ls -l /dev/fd/3; echo test2 >&3; cat $file} 3<> ${file::==(echo test)}
test
lrwx------ 1 stephane stephane 64 Jan 30 11:19 /dev/fd/3 -> /tmp/zshMLbER0
test2
एक बार कमांड समाप्त होने के बाद वह फाइल अपने आप हट जाती है।
यहाँ-फ़ाइलें या यहाँ-में तार bash
और zsh
हटाए गए अस्थायी फ़ाइलों के रूप में कार्यान्वित किए जाते हैं।
तो अगर तुम करते हो:
exec 3<<< test
फ़ाइल डिस्क्रिप्टर 3 एक हटाई गई अस्थायी फ़ाइल से जुड़ा है test\n
।
आप इसके साथ इसकी सामग्री प्राप्त कर सकते हैं:
cat <&3
यदि लिनक्स पर है, तो आप उस फ़ाइल को पढ़ या लिख भी सकते हैं /dev/fd/3
$ exec 3<<< test
$ cat <&3
test
$ echo foo > /dev/fd/3
$ cat /dev/fd/3
foo
(कुछ अन्य गोले पाइप का उपयोग करते हैं, या उपयोग कर सकते हैं /dev/null
यदि यहाँ डॉक्टर खाली है)।
कोई mktemp
POSIX उपयोगिता नहीं है। POSIX हालांकि एक mkstemp(template)
C API को निर्दिष्ट करता है , और m4
मानक उपयोगिता mkstemp()
उसी नाम से m4 फ़ंक्शन के साथ उस API को उजागर करती है ।
mkstemp()
आपको एक यादृच्छिक नाम के साथ एक फ़ाइल नाम देता है जिसे उस समय कहा जाता था जब फ़ंक्शन को कॉल नहीं किया जाता था। यह फ़ाइल को रेस-फ्री तरीके से 0600 अनुमतियों के साथ बनाता है।
तो, आप कर सकते हैं:
tmpfile=$(
echo 'mkstemp(template)' |
m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit
ध्यान दें कि बाहर निकलने पर आपको क्लीन-अप को संभालने की आवश्यकता होती है, हालाँकि यदि आपको फ़ाइल को एक निश्चित संख्या में लिखने और पढ़ने की आवश्यकता है, तो आप इसे यहाँ-डॉक्स / यहाँ की तरह बनाने के बाद इसे खोल सकते हैं और हटा सकते हैं- ऊपर स्ट्रिंग दृष्टिकोण:
tmpfile=$(
echo 'mkstemp(template)' |
m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit
# open once for writing, twice for reading:
exec 3> "$tempfile" 4< "$tempfile" 5< "$tempfile"
rm -f -- "$tmpfile"
cmd >&3 # store something in the temp file
exec 3>&- # fd no longer needed
# read the content twice:
cat <&4
cat <&5
आप एक बार पढ़ने के लिए फ़ाइल खोल सकते हैं, और दो रीड्स के बीच में रिवाइंड कर सकते हैं, हालाँकि ऐसी कोई POSIX उपयोगिता नहीं है जो उस रिवाइंडिंग ( lseek()
) को कर सके, इसलिए आप इसे POSIX स्क्रिप्ट ( zsh
( sysseek
बिल्टिन) और ksh93
( <#((...))
ऑपरेटर) में आंशिक रूप से नहीं कर सकते हैं हालांकि यह करो)।
<()
=(...)
:।
यहाँ Hauke Laging की लाइन में थोड़ा सुधार हुआ जवाब है:
#!/bin/bash
tmpfile=$(mktemp) # Create a temporal file in the default temporal folder of the system
# Lets do some magic for the tmpfile to be removed when this script ends, even if it crashes
exec {FD_W}>"$tmpfile" # Create file descriptor for writing, using first number available
exec {FD_R}<"$tmpfile" # Create file descriptor for reading, using first number available
rm "$tmpfile" # Delete the file, but file descriptors keep available for this script
# Now it is possible to work with the temporal file
echo foo >&$FD_W
echo bar >&$FD_W # Note that file descriptor always concatenates, not overwrites
cat <&$FD_R
आमतौर पर अस्थायी फ़ाइलों के साथ मेरा वर्कफ़्लो कुछ बैश स्क्रिप्ट के कारण होता है जिसका मैं परीक्षण कर रहा हूं। मैं tee
इसे ऊपर ले जाना चाहता हूं ताकि मैं देख सकूं कि यह काम कर रहा है और मेरी प्रक्रिया के अगले पुनरावृत्ति के लिए आउटपुट को बचा सकता है। मैंने एक फाइल बनाई है जिसका नाम हैtmp
#!/bin/bash
echo $(mktemp /tmp/$(date +"%Y-%m-%d_%T_XXXXXX"))
ताकि मैं इसका उपयोग कर सकूं
$ some_command --with --lots --of --stuff | tee $(tmp)
यादृच्छिक मूल्यों से पहले प्रारूपित प्रारूप मुझे पसंद है इसका कारण यह है कि यह मुझे उस tmp फ़ाइल को खोजने की अनुमति देता है जिसे मैंने अभी आसानी से बनाया है, और मुझे यह सोचने की ज़रूरत नहीं है कि अगली बार इसका नाम क्या है (और सिर्फ अपनी खतरे की स्क्रिप्ट प्राप्त करने पर ध्यान केंद्रित करें काम करने के लिए)।