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으로 이동합니다. 즉, 중간에 파일에서 한 줄을 읽는 동안 stdin을 저장, 교체 및 복원합니다.

read line1 < /etc/XX/cfg훨씬 쉬울 수 있지만 표시된 코드에만 기초하여 유효한 대체인지 ​​확인하는 것은 불가능합니다.

답변2

이를 syscalls에서 다시 캐스팅하려면(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

내가 이것을 읽는 방법은 - REDIRECTION의 bash 맨페이지 섹션을 기반으로 - stdin(fd0)이 fd4로 리디렉션된 다음 입력이 - /etc/XX/cfg에서 가져와서 stdinfd4에서 끝나는 것입니다.

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

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

관련 정보