예를 들어 명령을 실행할 때 test -l --hello check
:
쉘은 명령을 변수에 저장하고, $0="test"
쉘은 해당 바이너리를 실행하고, $1="-l"
바이너리는 변수를 읽고, 바이너리는 변수가 말하는 대로 수행합니다.$2="--hello"
$3="check"
표준 스트림이 바로 이러한 변수인가요?
@philip-couling에게 질문하세요(댓글이 제한되어 있기 때문에 여기에 질문합니다):
리디렉션 연산자와 파이프(<, >, |)에 대해 문의하고 싶으신 것 같습니다.
예,표준 스트림이것이 리디렉션과 파이프가 작동하는 방식입니다. 그렇죠?
텍스트 줄을 매개변수로 나누기
이는 명령 자체뿐만 아니라 매개변수/플래그도 저장합니다. 예를 들어, ls는 명령 부분이고 -la는 매개변수 부분입니다. 이것은 중요합니다. 예를 들어 비지박스의 경우 이는 단지 바이너리일 뿐이며 일반적으로 심볼릭 링크를 사용하여 호출됩니다(예를 들어 /bin/ls (경로에서 ls)를 실행하면 /bin/busybox에 대한 심볼릭 링크이므로 비지박스 바이너리에는 필요합니다. 명령과 해당 플래그를 아는 방법).
배열로 명령에 전달됨
배열로? $0..$last 변수를 사용하지 않나요?
읽거나 쓰기 위해 파일을 열면 운영 체제는 단순한 숫자인 "파일 설명자"를 제공합니다. 하위 프로세스는 상위 프로세스로부터 파일 설명자를 상속받습니다. 상위 항목에서 열린 모든 파일은 하위 항목에서도 열려 사용할 수 있습니다(파일을 열지 말라는 명시적인 지침 없이 파일을 열지 않은 경우).
각 파일 설명자는 숫자일 뿐입니다. 처음 세 개는 stdin(0) stdout(1) stderr(2)용입니다. posix의 STDERR_FILENO를 참조하세요. 내가 아는 한, 이는 기술적으로 예약되어 있지는 않지만 일반적으로 이 세 가지 설명자가 존재한다는 사실로 인해 다른 사람들이 동일한 번호를 사용하는 것이 방지됩니다.
소프트웨어 언어에는 표준 출력(예: echo 또는 print)에 쓰기 위한 특수 구문이 있을 수 있지만 실제로는 모든 바이너리가 수행하는 작업은 파일 설명자 번호 0에 쓰는 것입니다.
아, 이제 파일 디스크립터와 stdin, stdout, stderr가 0, 1, 2인 것으로 기억합니다. 이것들에 대한 설명이 정말 좋습니다! 그런데 문제는 명령의 출력이 모두 1과 2로 나온다는 것입니다. 그렇죠? 그럼 1번과 2번은 언제 클리어 되나요?
답변1
<
리디렉션 연산자와 파이프( , >
, ) 에 대해 문의하고 싶으신 것 같습니다 |
.
명령줄 인수의 경우 셸은 텍스트 줄을 인수로 나누어 명령에 배열로 전달됩니다. 셸 호출은 fork
새 프로세스를 생성한 다음 exec
새 명령을 시작하고 인수를 전달하는 데 사용됩니다.
리디렉션의 경우 상황이 좀 더 복잡합니다. 파일 이름은 직접 전달되지 않습니다. 대신 표준 스트림은 상위 프로세스에서 상속되며 셸은 fork
및 사이에서 이를 수정 해야 합니다 exec
.
읽거나 쓰기 위해 파일을 열면 운영 체제는 단순한 숫자인 "파일 설명자"를 제공합니다. 하위 프로세스는 상위 프로세스로부터 파일 설명자를 상속받습니다. 상위 항목에서 열린 모든 파일은 하위 항목에서도 열려 사용할 수 있습니다(파일을 열지 말라는 명시적인 지침 없이 파일을 열지 않은 경우).
각 파일 설명자는 숫자일 뿐입니다. 처음 3개는 stdin(0) stdout(1) stderr(2)용입니다. 바라보다STDERR_FILENOPOSIX에서. 내가 아는 한, 이는 기술적으로 예약되어 있지는 않지만 일반적으로 이 세 가지 설명자가 존재한다는 사실로 인해 다른 사람들이 동일한 번호를 사용하는 것이 방지됩니다.
echo
소프트웨어 언어에는 표준 출력에 쓰기 위한 특수 구문(예: 또는 ) 이 있을 수 있지만 print
실제로 바이너리가 수행하는 작업은 파일 설명자 번호 0에 쓰는 것뿐입니다.
리디렉션 연산자가 작동하는 방식은 셸이 파일을 열거나 파일 설명자를 가져오기 위한 파이프를 만든 다음 을 dup2
호출하기 전에 설명자를 세 개(0,1,2) 중 하나에 복사하는 것입니다 exec
.
따라서 하위 프로세스는 stdin, stdout 또는 stderr에서 열려 있는 내용을 결코 알 수 없습니다. 파일 설명자만 있으므로 운영 체제에 요청하면 더 많은 정보를 얻을 수 있습니다.