stdin이 fd4로 리디렉션되는 경우 읽기가 작동하는 이유는 무엇입니까?

stdin이 fd4로 리디렉션되는 경우 읽기가 작동하는 이유는 무엇입니까?

다음 스크립트는 무엇을 의미합니까?

exec 4<&0 0</etc/XX/cfg
read line1
exec 0<&4

fd0을 fd4로 리디렉션하고 "/etc/XX/cfg"를 fd0으로 리디렉션합니다.

그렇다면 왜 read여전히 작동합니까? 비어 있으면 안 되나요?

답변1

이는 stdin(FD0)을 FD4로 리디렉션하고, FD0을 /etc/XX/cfgFD0으로 리디렉션하고, FD0에서 행을 읽은 다음 FD4를 다시 FD0으로 이동합니다. 즉, 중간 파일에서 한 줄을 읽는 동안 표준 입력을 저장, 교체 및 복원합니다.

read line1 < /etc/XX/cfg훨씬 쉬울 수 있지만 표시된 코드만으로는 유효한 대체인지 ​​알 수 있는 방법이 없습니다.

답변2

C를 사용하여 시스템 호출로 다시 캐스팅하려면 다음을 수행하세요.

exec 4<&0 0</etc/XX/cfg

/* Duplicate fd0 as fd4.  */
dup2 (0, 4);

/* Open file on fd0.
   "open" always uses lowest available descriptor, so we don't need to check it. */
close (0);
open ("/etc/XX/cfg", O_RDONLY);

exec 0<&4

/* Close fd0 and duplicate fd4 as fd0.  */
dup2 (4, 0);

답변3

내가 이것을 읽는 방법은 - bash 매뉴얼 페이지의 리디렉션 섹션을 기반으로 - (fd0)을 fd4로 리디렉션한 다음 stdin입력을 받아 결국 fd4에 도달한다는 것입니다./etc/XX/cfgstdin

read line1그런 다음 fd4에서 꺼내서 fd0에 다시 넣어야 합니다.

데모를 통해 내가 의미하는 바를 더 잘 보여주고 이 작업을 수행하는 "이유"에 대해 답할 수 있습니다. 다른 줄을 추가하고 래퍼에 넣으면 다음과 같습니다.

$ vim ./test.sh
#!/bin/bash
exec 4<&0 0</etc/XX/cfg
read line1    # reads from fd4
exec 0<&4
read line2    # reads from fd0

echo $line1 
echo $line2

test.sh를 통해 파이프하거나 리디렉션할 수 있지만 stdin리디렉션을 통해 구성을 읽을 수도 있으므로 위의 코드에서는 "config"에서 값을 추출했습니다(파일 이름을 기반으로 가정했습니다. 좋지 않음 :)). 또한 stdin을 통해 처리합니다.

예를 들어:

$ ./test.sh < somefile
$ cat somefile | ./test.sh

이것이 설명되기를 바랍니다.

관련 정보