क्या पहले से उनकी स्पष्ट सूची के बिना सभी खुले फ़ाइल विवरणकों को बंद करने का एक तरीका है?
क्या पहले से उनकी स्पष्ट सूची के बिना सभी खुले फ़ाइल विवरणकों को बंद करने का एक तरीका है?
जवाबों:
शाब्दिक रूप से उत्तर देने के लिए, सभी खुले फ़ाइल विवरणों को बंद करने के लिए bash
:
for fd in $(ls /proc/$$/fd); do
eval "exec $fd>&-"
done
हालांकि यह वास्तव में एक अच्छा विचार नहीं है क्योंकि यह मूल फ़ाइल विवरणों को बंद कर देगा जो इनपुट और आउटपुट के लिए शेल की आवश्यकता है। यदि आप ऐसा करते हैं, तो आपके द्वारा चलाए जाने वाले कार्यक्रमों में से कोई भी टर्मिनल पर अपना आउटपुट प्रदर्शित नहीं करेगा (जब तक कि वे tty
डिवाइस पर सीधे नहीं लिखते )। यदि मेरे परीक्षणों को बंद करने stdin
( exec 0>&-
) में तथ्य सिर्फ एक इंटरैक्टिव शेल से बाहर निकलने का कारण बनता है।
जो आप वास्तव में करना चाह रहे हैं वह सभी फ़ाइल विवरणों को बंद करने के लिए है जो शेल के मूल ऑपरेशन का हिस्सा नहीं हैं। ये हैं 0 के लिए stdin
, 1 के लिए stdout
और 2 के लिए stderr
। इसके ऊपर कुछ गोले डिफ़ॉल्ट रूप से अन्य फ़ाइल डिस्क्रिप्टर को खोलते हैं। में bash
, उदाहरण के लिए, आप 255 (भी टर्मिनल आई / ओ के लिए) और में है dash
10 मेरे पास है, जो अंक के /dev/tty
बजाय विशिष्ट से tty
/ pts
उपकरण टर्मिनल का उपयोग कर रहा है। 0, 1, 2 और 255 के अलावा सब कुछ बंद करने के लिए bash
:
for fd in $(ls /proc/$$/fd); do
case "$fd" in
0|1|2|255)
;;
*)
eval "exec $fd>&-"
;;
esac
done
यह भी ध्यान रखें कि eval
जब फ़ाइल वर्णनकर्ता एक चर में निहित पुनः निर्देशित की आवश्यकता है, नहीं तो bash
चर का विस्तार होगा, लेकिन यह आदेश के हिस्से पर विचार (इस मामले में यह करने की कोशिश करेगा exec
आदेश 0
या 1
या जो भी फ़ाइल वर्णनकर्ता आप पास करने की कोशिश कर रहे हैं)।
नोट: इसके अलावा ls
(जैसे /proc/$$/fd/*
) के बजाय एक ग्लोब का उपयोग करने से ग्लोब के लिए एक अतिरिक्त फ़ाइल डिस्क्रिप्टर खुलता है, इसलिए ls
यहां सबसे अच्छा समाधान लगता है।
की पोर्टेबिलिटी के बारे में अधिक जानकारी के लिए /proc/$$/fd
, कृपया फ़ाइल डिस्क्रिप्टर लिंक की पोर्टेबिलिटी देखें । यदि /proc/$$/fd
अनुपलब्ध है, तो $(ls /proc/$$/fd)
, lsof
(यदि वह उपलब्ध है) का उपयोग करने के लिए प्रतिस्थापन में एक गिरावट होगी $(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-)
।
/proc
केवल लिनक्स के तहत उपलब्ध है।
/proc/PID/fd
बहुत पोर्टेबल नहीं हैं, तो आप सही होंगे । लेकिन यह कहना कि /proc
केवल लिनक्स के तहत उपलब्ध है एक सही बयान नहीं है।
<&-
फॉर्म का उपयोग करती हैं , क्या यह कोई अलग / आवश्यक है?
बैश (4.1 और आगे, वर्ष 2009 और बाद के) के हाल के संस्करणों में आप शेल वर्णक का उपयोग करके फ़ाइल डिस्क्रिप्टर को बंद करने के लिए निर्दिष्ट कर सकते हैं:
for fd in $(ls /proc/$$/fd/); do
[ $fd -gt 2 ] && exec {fd}<&-
done
फीचर कोर्न शेल में पहले से ही था (1993 के बाद से?) लेकिन जाहिर तौर पर बैश में अपना रास्ता बनाने में कुछ समय लगा।
वर्तमान शेल के i / o / e को छोड़कर सभी फ़ाइल डिस्क्रिप्टर को साफ़ करें, लेकिन प्रदान की गई दलीलों को भी शामिल नहीं करता है
clear_fds() {
for fd in $(compgen -G "/proc/$BASHPID/fd/*"); do
fd=${fd/*\/}
if [[ ! " $* " =~ " ${fd} " ]]; then
case "$fd" in
0|1|2|255)
;;
*)
eval "exec $fd>&-"
;;
esac
fi
done
}
"Eval" के बिना एक और तरीका है, फॉर्म का उपयोग करना है:
$ exec {var_a}>> file.txt
$ echo $var_a
10
$ ls -l /proc/self/fd/10
l-wx------ 1 0 0 64 Dec 11 18:32 /proc/self/fd/10 -> /run/user/0/tmp/file.txt
$ echo "aaaaa" >&$var_a
$ cat file.txt
aaaaa
$ exec {var_a}>&-
$ ls /proc/self/fd/10
ls: cannot access '/proc/self/fd/10': No such file or directory
नहीं। कर्नेल एक समय में केवल एक एफडी को बंद कर सकता है, और bash में FD के लिए "समूह कमांड" नहीं है।
for fd in $(ls -1 /proc/27343/fd); do echo exec $fd">&"-; done
echo
और निकालें"
परीक्षण बाद ।
यदि यह शेल के लिए नहीं है, लेकिन कमांड चलाने के लिए है तो आप उपयोग कर सकते हैं nohup
।
>&-
एक पैरामीटर नहीं हो सकता है; पुनर्निर्देशन को पैरामीटर विस्तार से पहले पार्स किया जाता है।
exec {fd}>&-
काम करता है।