파일 디스크립터를 저장하려면 다른 fd에 파일 디스크립터를 복제하십시오. 해당 파일의 경로를 저장하는 것만으로는 충분하지 않습니다. 시작 모드, 시작 플래그, 파일 내 현재 위치 등을 저장해야합니다. 물론 익명의 파이프 또는 소켓의 경우 경로가 없으므로 작동하지 않습니다. 저장하려는 것은 fd가 참조 하는 열린 파일 설명 이며, fd를 복제하면 실제로 동일한 fd 파일 설명 으로 새 fd를 리턴합니다 .
Bourne과 같은 쉘을 사용하여 파일 디스크립터를 다른 파일 디스크립터에 복제하는 구문은 다음과 같습니다.
exec 3>&1
위의 fd 1은 fd 3에 복제됩니다.
fd 3이 이미 열려 있던 것은 닫히지 만 fd 3 ~ 9 (일반적으로 최대 99까지 yash
)는 해당 목적을 위해 예약되어 있으며 0, 1 또는 2와 반대되는 특별한 의미는 없습니다. 쉘은 자체 내부 비즈니스에 사용하지 않는 것을 알고 있습니다. fd 3가 미리 열린 유일한 이유는 스크립트 1 에서 실행했거나 호출자가 유출 했기 때문 입니다.
그런 다음 stdout을 다른 것으로 변경할 수 있습니다.
exec > /dev/null
나중에 stdout을 복원하려면 다음을 수행하십시오.
exec >&3 3>&-
( 3>&-
더 이상 필요없는 파일 디스크립터를 닫는 중).
이제 문제는 ksh를 제외하고 그 이후에 실행하는 모든 명령 exec 3>&1
이 fd 3을 상속한다는 것입니다. 그것은 fd 누출입니다. 일반적으로 큰 문제는 아니지만 문제가 발생할 수 있습니다.
ksh
세트 근접에-간부 (2 이상 FDS를 위해) 그 FDS에 플래그를하지만, 다른하지 쉘과 다른 쉘은 수동으로 세트에 그 깃발을 어떤 방법이 없습니다.
다른 쉘의 해결 방법은 다음과 같이 각 명령마다 fd 3을 닫는 것입니다.
exec 3>&-
exec > file.log
ls 3>&-
uname 3>&-
exec >&3 3>&-
번거로운. 여기서 가장 좋은 방법은 전혀 사용하지 않고 exec
명령 그룹을 리디렉션하는 것입니다.
{
ls
uname
} > file.log
, 거기는 표준 출력 저장하고 나중에 복원 할을 담당 쉘은 (그리고 그것은 99 위, 9 위 (A (FD) 상을 복제하여 내부적으로합니까 yash
과) 가까운 온 간부 플래그가 설정).
참고 1
이제 fd 3-9를 광범위하게 또는 기능적으로 사용하는 경우, 특히 스크립트에서 해당 fd를 사용할 수있는 타사 코드를 사용하는 경우 이러한 fd 3-9를 관리하는 것은 번거롭고 문제가 될 수 있습니다.
일부 쉘 ( zsh
, bash
, ksh93
, 모든 기능 (추가 의 올리버 고기 잡이 통발에 의해 제안zsh
이 경우에 도움이 대신 10 위의 첫 번째 무료 FD를 할당 할 수있는 대안 구문이 그들의 개발자들 사이에서 논의 된 후 2005 년 같은시기를)) :
myfunction() {
local fd
exec {fd}>&1
# stdout was duplicated onto a new fd above 10, whose actual value
# is stored in the fd variable
...
# it should even be safe to re-enter the function here
...
exec >&"$fd" {fd}>&-
}