Önceden açık bir liste olmadan tüm açık dosya tanımlayıcılarını kapatmanın bir yolu var mı?
Önceden açık bir liste olmadan tüm açık dosya tanımlayıcılarını kapatmanın bir yolu var mı?
Yanıtlar:
Kelimenin tam anlamıyla cevaplamak için aşağıdakiler için tüm açık dosya tanımlayıcılarını kapatın bash:
for fd in $(ls /proc/$$/fd); do
eval "exec $fd>&-"
done
Ancak bu gerçekten iyi bir fikir değildir, çünkü kabuğun girdi ve çıktı için ihtiyaç duyduğu temel dosya tanımlayıcılarını kapatacaktır. Bunu yaparsanız, çalıştırdığınız programların hiçbiri çıktılarını terminalde göstermez ( ttycihaza doğrudan yazmadıkları sürece ). Eğer testlerimde gerçeği closing stdin( exec 0>&-) sadece interaktif bir kabuk çıkmak neden olur.
Aslında yapmak isteyebileceğiniz şey, kabuğun temel işleminin bir parçası olmayan tüm dosya tanımlayıcılarını kapatmaktır. Bunlar için 0 stdin, 1 için stdoutve 2 için stderr. Bunun üzerine bazı kabuklar varsayılan olarak açık olan diğer dosya tanımlayıcılarına sahip gibi görünüyor. Olarak bash, örneğin, 255 (aynı zamanda, terminal I / O için) ve var dashI olan 10, puan /dev/ttyyerine belirli daha tty/ ptscihazın uç kullanıyor. 0, 1, 2 ve 255 dışında her şeyi kapatmak için bash:
for fd in $(ls /proc/$$/fd); do
case "$fd" in
0|1|2|255)
;;
*)
eval "exec $fd>&-"
;;
esac
done
Ayrıca Not evalbir değişken içerdiği dosya tanımlayıcısı yönlendirme yaparken değilse, gerekli bashdeğişkeni genişletmek ancak komuta parçası bunu dikkate alacaktır (bu durumda çalışacaklarını execkomuta 0veya 1veya hangisi dosya tanıtıcı size yakın çalıştığınız).
NOT: Ayrıca ls(örneğin /proc/$$/fd/*) yerine bir glob kullanmak glob için ekstra bir dosya tanımlayıcı açmak lsgibi görünüyor , bu yüzden burada en iyi çözüm gibi görünüyor.
Taşınabilirliği hakkında daha fazla bilgi için /proc/$$/fdlütfen Dosya tanımlayıcı bağlantılarının taşınabilirliği konusuna bakın . Kullanılamıyorsa /proc/$$/fd, (varsa) $(ls /proc/$$/fd)kullanarak, yerine bir damla lsofolur $(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-).
/procyalnızca Linux altında kullanılabilir.
/proc/PID/fdçok taşınabilir olmadığını söyleseydin haklısın . Ancak bunun /procsadece Linux altında mevcut olduğunu söylemek doğru bir ifade değildir .
<&-formu kullanıyor, farklı / gerekli mi?
Bash son sürümlerinde (daha sonra 4.1 ve sonrası, 2009 yılı ve) size olabilir bir kabuk değişkeni kullanarak kapatmak için dosya tanımlayıcısı belirtin:
for fd in $(ls /proc/$$/fd/); do
[ $fd -gt 2 ] && exec {fd}<&-
done
Özellik zaten Korn kabuğundaydı (1993'ten beri?) Ama görünüşe göre Bash'a girmesi biraz zaman aldı.
Geçerli kabuğun i / o / e dışındaki tüm dosya tanımlayıcılarını temizler, ancak bağımsız değişken olarak sağlananları da hariç tutar
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
}
Hiç "eval" olmadan başka bir yolu, formu kullanmaktır:
$ 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
Hayır. Çekirdek aynı anda yalnızca bir FD'yi kapatabilir ve bash'ın FD'ler için "grup komutları" yoktur.
for fd in $(ls -1 /proc/27343/fd); do echo exec $fd">&"-; done
Testten sonra echove "testini kaldırın .
Bu, kabuğun kendisi için değil, bir komutun çalıştırılması içinse kullanabilirsiniz nohup.
>&-bir parametre olamaz; yeniden yönlendirme, parametre genişletmeden önce ayrıştırılır.
exec {fd}>&-çalışıyor.