미리 명시적으로 나열하지 않고 열려 있는 모든 파일 설명자를 닫는 방법이 있습니까?
답변1
문자 그대로 답변, 닫기모두파일 설명자 열기 bash
:
for fd in $(ls /proc/$$/fd); do
eval "exec $fd>&-"
done
그러나 이는 쉘 입력 및 출력에 필요한 기본 파일 설명자를 닫으므로 실제로는 좋은 생각이 아닙니다. 이렇게 하면 실행하는 모든 프로그램은 tty
장치에 직접 쓰지 않는 한 터미널에 출력을 표시하지 않습니다. 실제로 제가 테스트한 결과 stdin
( exec 0>&-
)를 닫으면 대화형 셸이 종료되었습니다.
실제로 수행할 작업은 기본 셸 작업의 일부가 아닌 모든 파일 설명자를 닫는 것입니다. 이들은 0 stdin
, 1 stdout
및 2 입니다 stderr
. 이 외에도 일부 쉘은 기본적으로 다른 파일 설명자를 여는 것 같습니다. bash
예를 들어 에는 255(터미널 I/O에도 사용됨)가 있는 반면, dash
제 경우에는 10이 있는데 이는 /dev/tty
터미널이 사용하는 특정 tty
/device가 아님을 나타냅니다. 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
또한 (예: ) 대신 glob을 사용하면 /proc/$$/fd/*
glob에 대한 추가 파일 설명자가 열리는 것처럼 보이므로 ls
여기서는 가장 좋은 솔루션인 것 같습니다.
고쳐 쓰다
이식성에 대한 자세한 내용은 /proc/$$/fd
다음을 참조하세요.파일 디스크립터 링크 이식성. 이용할 수 없는 경우에는 /proc/$$/fd
대체품(사용 가능한 경우)을 드립니다.$(ls /proc/$$/fd)
lsof
$(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-)
답변2
최신 버전의 Bash(4.1 이상, 2009 이상)에서는할 수 있는셸 변수를 사용하여 닫을 파일 설명자를 지정합니다.
for fd in $(ls /proc/$$/fd/); do
[ $fd -gt 2 ] && exec {fd}<&-
done
이 기능은 Korn 쉘(1993년부터?)에 있었지만 Bash에 적용되기까지 시간이 좀 걸렸던 것 같습니다.
답변3
현재 쉘의 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
}
답변4
캔트. 커널은 한 번에 하나의 FD만 닫을 수 있으며 bash에는 FD에 대한 "그룹 명령"이 없습니다.
for fd in $(ls -1 /proc/27343/fd); do echo exec $fd">&"-; done
echo
및 테스트 후 제거하십시오 "
.
셸 자체가 아니라 명령을 실행하는 경우에는 nohup
.