আগে থেকেই তাদের সুস্পষ্ট তালিকা না রেখে সমস্ত উন্মুক্ত ফাইল বর্ণনাকারী বন্ধ করার কোনও উপায় আছে কি?
আগে থেকেই তাদের সুস্পষ্ট তালিকা না রেখে সমস্ত উন্মুক্ত ফাইল বর্ণনাকারী বন্ধ করার কোনও উপায় আছে কি?
উত্তর:
আক্ষরিক উত্তর দিতে, এর জন্য সমস্ত ওপেন ফাইল বর্ণনাকারী বন্ধ করতে 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
এটি কেবল লিনাক্সের অধীনে উপলব্ধ তা সঠিক বিবৃতি নয়।
<&-
ফর্মটি ব্যবহার করে , এটি কি অন্যরকম / প্রয়োজনীয়?
বাশের সাম্প্রতিক সংস্করণগুলিতে (৪.১ এবং পরবর্তী বছর, ২০০৯ এবং তার পরে) আপনি শেল ভেরিয়েবল ব্যবহার করে ফাইল ডেস্ক্রিপ্টরটি নির্দিষ্ট করতে পারেন :
for fd in $(ls /proc/$$/fd/); do
[ $fd -gt 2 ] && exec {fd}<&-
done
বৈশিষ্ট্যটি ইতিমধ্যে কর্ন শেলের মধ্যে ছিল (১৯৯৩ সাল থেকে) তবে স্পষ্টতই কিছুটা সময় নিয়েছে বাশে প্রবেশের জন্য।
বর্তমান শেলের আই / ও / ই ব্যতীত সমস্ত ফাইল বর্ণনাকারী সাফ করুন, তবে আর্গুমেন্ট হিসাবে সরবরাহিত ফাইলগুলি বাদ দেয়
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
}
একেবারে "ইভাল" ছাড়াই অন্য উপায় হ'ল ফর্মটি ব্যবহার করা:
$ 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
না। কার্নেলটি একবারে কেবল একটি এফডি বন্ধ করতে পারে এবং বাশের এফডিগুলির জন্য "গ্রুপ কমান্ড" নেই।
for fd in $(ls -1 /proc/27343/fd); do echo exec $fd">&"-; done
পরীক্ষার পরে echo
এবং অপসারণ করুন "
।
এটি যদি নিজেই শেলের জন্য না হয়ে চালিত কমান্ডের জন্য হয় তবে আপনি ব্যবহার করতে পারেন nohup
।
>&-
প্যারামিটার হতে পারে না; পুনঃনির্দেশটি পরামিতি প্রসারণের পূর্বে পার্স করা হয়েছে।
exec {fd}>&-
কাজ করে।