상술 한 바와 같이여기open()
, 리디렉션은 파일 쓰기 에 사용됩니다 . 내부(?) 파일 설명자는 셸에 생성되어 필요할 때 사용됩니다.
내부 설명자는 스크립트 전체 기간 동안 생성됩니까, 아니면 쉘 수명 동안 생성됩니까? 시간이 지남에 따라, 여러 작업 등으로 인해 파괴됩니까?
내 말은 내장 작업을 위해 쉘 자체에서 열리는 파일의 파일 설명자입니다. 각 작업에 대해 설명자가 생성되고 파일이 열립니까? 얼마나 오래 보관되나요? 예:
#!/bin/bash
>>x echo something
...do many other things not related to the file x
>>x echo something more
두 번째 작업까지 첫 번째 설명자 인스턴스가 유지됩니까?
터미널에서 사용하는 쉘은 어떻습니까? 때로는 며칠, 심지어 몇 주 동안 세션을 계속할 때도 있습니다. 쉘 내장 기능을 사용하여 조작하는 모든 파일에 대한 설명자가 여전히 유지됩니까?
답변1
완료되면 닫힙니다. 쉘은 실행되는 각 명령에 대해 3개의 파일 설명자 0, 1, 2를 생성합니다. 이것은 단지 숫자일 뿐이며 이 숫자는 재사용됩니다. 쉘은 설명자를 재사용하기 전에 파일을 닫습니다.
파일 설명자는 다른 프로세스에도 전달됩니다. 백그라운드에 프로세스가 있는 경우에도 여전히 파일 설명자가 있습니다.
예제에서는 를 사용합니다 3>&1
. 이는 파일 설명자 3이 현재 설명자 1이 참조하는 파일을 참조하도록 만드는 것을 의미합니다.
답변2
간단히:명령이 완료되면 쉘은 리디렉션과 관련된 파일 설명자를 거의 확실하게 즉시 닫습니다.
세부 사항:다음을 통해 열린 파일을 닫는다는 명시적인 언급은 없습니다.리디렉션POSIX에서 (내가 아는 한). 하지만 즉시 닫지 않으면 별 소용이 없습니다.
이것모든 명령으로 시작된 환경 규칙추가 파일 설명자를 전달하는 것은 허용되지 않습니다. 쉘은 포함되어서는 안 되는 명령을 시작할 때 저장된 추가 파일 설명자를 닫도록 주의해야 합니다.
일반적인 > filename
출력 리디렉션을 사용하면 파일 설명자가 저장된 경우에도 각 명령을 시작할 때 파일을 잘라야 합니다. 그리고어느관련 파일의 이름이 바뀌거나 동시에 삭제되면 저장된 파일 설명자가 잘못된 파일을 가리킵니다.
예를 들어, 첫 번째에 대해 열린 fd가 echo
열려 있고 두 번째에 대해 그대로 사용되는 경우 올바르게 실행되지 않습니다.
echo foo >> x; mv x y; echo bar >> x
외부 프로그램을 시작하기 위한 일반적인 fork+exec 모델을 사용하면 명령이 종료될 때 파일을 자동으로 닫는 것이 매우 쉽습니다. 셸은 먼저 fork()
자식 프로세스에서 필요한 파일을 연 다음 이를 호출하여 exec()
자식 프로세스를 실제 명령으로 바꾸면 됩니다. 하위 프로세스가 종료되면 열려 있던 모든 파일이 자동으로 닫힙니다.
존재하다awk
그러나 출력 리디렉션 구문은 셸과 유사하지만 열려 있는 모든 파일은 명시적으로 닫히지 않는 한 스크립트가 종료될 때까지 열린 상태로 유지됩니다. 이렇게 하면 한 번만 열리고 foo
인쇄 간에는 잘리지 않습니다.
awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'