Bash에서 모든 파일 설명자를 닫습니다.

Bash에서 모든 파일 설명자를 닫습니다.

미리 명시적으로 나열하지 않고 열려 있는 모든 파일 설명자를 닫는 방법이 있습니까?

답변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가 아님을 나타냅니다. pts0, 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.

관련 정보