쉘에는 서로 동일한 표준 입력, 표준 출력, 표준 오류 명령이 있습니까?

쉘에는 서로 동일한 표준 입력, 표준 출력, 표준 오류 명령이 있습니까?

예를 들어 bash는 /bin/bash 아래에 있습니다. 이는 명령이고 각 명령에 표준 입력, 표준 출력, 표준 오류의 세 가지(0,1,2) 구멍이 있음을 의미합니다.

이것이 쉘에 대해서도 100% 사실입니까, 아니면 명령이나 프로세스로서의 쉘의 특별한 의미와 다른 점이 있습니까?

답변1

다른 프로그램과 똑같습니다. 이를 통해 다른 프로그램처럼 I/O를 리디렉션하고 파이프할 수 있습니다.

echo "cat filename" | bash

파이프에서 표준 입력을 읽을 cat filename때 명령 을 실행합니다 .bash

bash -c "echo foo" > filename

명령 이 실행되고 echo foo출력이 파일로 리디렉션됩니다.

Unix에서는 쉘에 "특별한" 것이 없습니다. 이는 다른 프로그램을 실행하는 것이 주요 목적인 일반 프로그램일 뿐입니다.

답변2

몇 가지 용어를 구별해 보겠습니다.

명령는 쉘에 입력하는 것입니다. 그것은별명또는쉘 기능, 또는 다음을 참조할 수도 있습니다.실행 가능 파일.

실행 가능 파일될 수 있습니다바이너리 실행 가능(즉, 기계어 코드를 직접 포함하는 것) 또는스크립트. 스크립트에는 bash 스크립트, sh 스크립트, perl 스크립트, awk 스크립트, sed 스크립트, python 스크립트 등이 포함됩니다. 알.

스크립트의 처음 2바이트(실행 파일로 직접 실행하려는 경우)는 이어야 합니다 #!. 이는 개행 문자를 읽을 때까지 추가 바이트를 읽도록 커널에 신호를 보내는 "마법의 숫자"입니다. 해당 바이트를 경로바이너리 실행 가능, 공백으로 구분된 단일 인수(예: #!/bin/awk -f)를 사용하고 실행합니다.저것인수로 전달된 스크립트 자체에 대한 경로가 포함된 실행 가능한 바이너리입니다.

궁극적으로 커널이 실제로 실행할 수 있는 유일한 것은 기계어 코드, 즉 바이너리 실행 파일입니다. sh, bash, perl, python, awk 등과 같은 바이너리 실행 파일. 알. 호출된다통역사. 그들은 스크립트를 해석하고 해당 지침을 실행합니다. 하지만 실행되려면 기계어 자체에 존재해야 합니다.

프로그램(바이너리 실행 파일)이 실제로 커널에 의해 실행될 때, 프로그램은프로세스. 바이너리 실행 파일은 지침이 포함된 파일일 뿐입니다. ㅏ프로세스"프로그램의 실행 중인 인스턴스"입니다. 보다 구체적으로 이는 관련 메모리, 환경 변수, 프로세스 ID(PID)가 있는 커널에 내장된 추상화입니다.파일 설명자입력과 출력 및 기타 속성에 사용할 수 있습니다. 실행 파일을 "동시에" 두 번 이상 실행할 수 있습니다(단일 코어 시스템에서 문자 그대로 동시에는 아니지만 커널이 CPU 주기를 할당하는 방식으로 인해).~인 것 같다동시) 실행 중인 각 인스턴스는 모두 동일한 프로그램의 인스턴스이더라도 서로 다른 프로세스가 됩니다.

0, 1, 2(표준 입력, 표준 출력, 표준 오류)는 다음과 같습니다.파일 설명자. 사실, 그것들이 존재한다는 것은 관례에 의해서만 가능합니다. 이러한 파일 설명자를 전혀 제공하지 않고도 C를 사용하여 다른 프로그램을 시작(실행)(다양한 바이너리 실행 파일 실행)하는 프로그램을 만들 수 있습니다. 하지만,표준 프로그램은 모두 파일 설명자 0, 1, 2의 가용성을 가정하여 작성되었으므로 아마도 오류만 발생하고(대부분의 경우) 프로그램이 올바르게 작동하지 않을 것입니다.

이것을 완전히 이해하려면 다음을 이해해야 합니다.프로세스가 어떻게 발생하는지. 이것은 탄생의 기적과 조금 비슷합니다. ;) 모든 프로세스는 다음에 의해 시작되어야 합니다.또 다른프로세스. 시스템을 부팅할 때 첫 번째 프로세스가 어떻게 시작되는지 걱정하지 않고 PID 1이 있는 프로세스를 "init"라고 하며 운영 체제가 작동하는 데 필요한 다른 기본 프로세스를 시작합니다.

프로세스가 다른 프로세스를 시작하는 방법은 두 가지 기본 단계로 구성됩니다.포크그리고집행자 둘 다 시스템 호출입니다. 즉, 프로세스가 보내는 작업/요청입니다.커널에이는 커널만이 실제로 수행할 수 있습니다.

"포크"는 (간단히 말해서) "커널, 내 복사본을 만들어 주세요"를 의미합니다. ("Me"는 실행 중인 프로세스입니다.) 커널은 프로세스의 파일 설명자, 메모리, 실행 상태(인스턴스인 프로그램을 구성하는 명령을 따르는 위치) 등 프로세스의 완전한 복사본을 만듭니다. 환경 변수 등. 따라서 이는 프로세스의 "복제본"입니다. 이제 사본과 원본을 어떻게 구분할 수 있습니까? 단 한 가지: fork시스템 호출 의 반환 상태입니다 . 하위 프로세스는 "0"(성공)을 얻고 상위 프로세스는 새로 생성된 하위 프로세스의 PID를 가져옵니다. 따라서 이 반환 상태를 검사함으로써 각 프로세스는 지금 무엇을 해야 하는지 알아낼 수 있습니다(기억하세요, 그들은 동일한 지침 세트를 따르고 있기 때문입니다!).

"Exec"은 실제로는 "execve()"입니다. 간단히 말해서, 커널에게 "커널 부탁드립니다."라고 묻는 것입니다.바꾸다나(나는 프로세스입니다)를 ______ 파일에 지정된 프로그램 인스턴스와 함께 사용합니다." 그리고 프로그래머는 또한인수새로운 프로세스에는환경(환경 변수 배열)을 갖게 됩니다.

따라서 셸에 명령을 입력하면 실제로 일어나는 일은(대부분의 경우 와 같은 셸 내장 명령과 같은 특수한 경우를 무시하고 cd) 셸(실행 중인 프로세스)입니다.포크,그런 다음간부당신이 지정한 명령.

와 같은 출력 또는 입력 리디렉션을 수행한 경우 /bin/echo hello > /dev/null포크된 하위 프로세스는exec에코를 하기 전에/dev/null은 그에 따라 파일 설명자를 조정하므로 파일 설명자 1(이 예에서는) 이 터미널 대신 또는 이전 위치 에 연결됩니다 .

따라서 실행 파일의 실행 중인 인스턴스는 /bin/bash입력을 읽을 수 있는 파일 설명자 0, 출력을 쓸 수 있는 파일 설명자 1, 오류를 읽고 쓸 수 있는 파일 설명자 2를 사용할 수 있을 것으로 예상합니다. 메시지 및 유사한 입/출력.

관련 정보