bash에서 모든 파일 설명자를 닫습니다. 사전에 명시적인 목록없이 모든

사전에 명시적인 목록없이 모든 열린 파일 디스크립터를 닫을 수있는 방법이 있습니까?



답변

말 그대로 대답하려면 다음에 대해 열려있는 모든 파일 설명자를 닫으 십시오 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에 I가있는 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 (예 🙂 대신 glob를 사용하면 glob에 /proc/$$/fd/*대한 추가 파일 디스크립터가 열려있는 ls것 같습니다.

최신 정보

이식성에 대한 자세한 내용 은 파일 디스크립터 링크의 이식성을/proc/$$/fd 참조하십시오 . 경우 교체에 사용할 수없는 후, 드롭 인 사용은, (즉, 사용할 수있는 경우)이 될 것이다 ./proc/$$/fd$(ls /proc/$$/fd)lsof$(lsof -p $$ -Ff | grep f[0-9] | cut -c 2-)


답변

최신 버전의 Bash (4.1 이상, 2009 년 이후) 에서는 셸 변수를 사용하여 닫을 파일 설명자를 지정할 수 있습니다 .

for fd in $(ls /proc/$$/fd/); do
    [ $fd -gt 2 ] && exec {fd}<&-
done

이 기능은 이미 Korn 쉘에 있었지만 (1993 년 이후) Bash로 들어가는 데 시간이 걸렸습니다.


답변

현재 쉘의 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


답변

커널은 한 번에 하나의 FD 만 닫을 수 있으며 bash에는 FD에 대한 “그룹 명령”이 없습니다.

for fd in $(ls -1 /proc/27343/fd); do echo exec $fd">&"-; done

echo"테스트 후를 제거하십시오 .

이것이 쉘 자체가 아니라 명령이 실행되는 경우 사용할 수 있습니다 nohup.


답변