다음 두 가지 테스트 파일이 있습니다.
test1 test2
둘 다 비어 있습니다. 이제 다음 명령을 실행합니다.
$ cat > test1
Enter
This is a test file
Enter
Ctrl+D
$ cat > test2
Enter
This is another test file
Enter
^C
Ctrl+C
$
이제 두 파일의 내용을 모두 확인합니다.
$ cat test1
This is a test file
$ cat test2
This is another test file
$
그렇다면 위의 두 가지 방법을 사용하여 동일한 결과를 얻으면 결과에 실제 차이가 있습니까?
답변1
명령이 실행 되면 cat
터미널이표준 입력 모드. 쉽게 말하면 터미널이라는 뜻이다.라인 규율라인 편집 처리 및 모든 응답특수 문자터미널 구성(명령을 통해 확인 및 설정 가능 stty
)
이 명령은 호출이 읽은 0바이트를 반환할 때까지 표준 입력에서 cat
단순히 ping을 보냅니다 (이것은 파일 끝을 누르는 POSIX 규칙입니다).read()
read()
터미널에는 실제 "끝"이 없습니다. 그러나 read()
터미널 장치가 0바이트를 반환하는 경우가 있습니다 . 라인 규칙이 "EOF" 특수 문자를 수신하면 read()
당시 구성된 내용에 관계없이 당시 편집 버퍼에 있던 모든 내용이 반환됩니다. 편집 버퍼가 비어 있으면 읽은 0바이트가 반환되어 종료 read()
됩니다 .cat
cat
또한 기본 동작이 프로세스를 종료하는 신호에 대한 응답으로 종료됩니다. 라인 분야는 또한 특수 문자에 대한 응답으로 신호를 생성합니다. "INTR" 및 "QUIT" 특수 문자는 해당 프로세스를 포함할 포그라운드 프로세스(그룹)로 신호가 전송되도록 INT
합니다 . 이러한 신호에 대한 기본 작업은 프로세스를 종료하는 것입니다 .QUIT
cat
cat
이로 인해 관찰 가능한 차이가 발생합니다.
- Ctrl+ D이 동작은 EOT 특수문자인 경우에만 발생합니다. 이것은대개그렇긴 한데 그렇지 않네요~ 해야 하다사례. 또한 Ctrl+는 CINTR 특수 문자인 경우에만 작동합니다.
- Ctrl+는 해당 시점에 행이 실제로 비어 있지 않은 경우 D종료를 유발하지 않습니다 . 그러나 +는
cat
인터럽트를 생성합니다.CtrlC cat
C의 간단한 구현은 질문에 표시된 것처럼 파일을 가리키는 것으로 발견되면 버퍼링된 stdout을 방지합니다. 이론적으로 에 의해 종료되면cat
버퍼링되었지만 아직 출력되지 않은 행이 손실될 수 있습니다SIGINT
.실제로 BSD 및 GNU C 라이브러리는 C 또는 C++ 언어 표준에 설명되지 않은 버퍼링 모드를 구현합니다. 파일이나 파이프로 리디렉션될 때의 표준 출력은 다음과 같습니다.스마트 버퍼링. C 라이브러리가
read()
터미널 장치에 열려 있는 파일 설명자에서 새 줄을 시작하려고 할 때마다 표준 출력을 플러시한다는 점을 제외하면 블록 버퍼링됩니다. (엄밀히 말하면, BSD와 GNU C 라이브러리는 정확히 동일한 의미를 구현하지 않고 그 이상을 수행하지만 이 동작은 공통된 하위 집합입니다.) 따라서 인터럽트 신호가cat
위에 구축될 때 버퍼링된 출력이 발생하지 않습니다 . 잃어버린. C 라이브러리.- 물론
cat
명령 파이프라인의 일부인 경우 일부다른cat
프로세스는 데이터가 출력 파일에 도달하기 전에 다운스트림으로 버퍼링할 수 있습니다. 따라서 라인 규칙이SIGINT
파이프라인의 모든 프로세스를 종료하도록 전송하면(기본적으로) 버퍼링되었지만 아직 기록되지 않은 입력 데이터는 손실되는 반면,cat
"EOF" 특수 문자를 사용하여 정상적으로 종료하면 파이프라인이 모든 데이터와 함께 정상적으로 종료됩니다. 이전에 다운스트림 프로세스로 전달됨그것EOF 명령 수신그것은read()
표준 입력입니다.
이는 대화형 쉘이 입력 행을 읽을 때 발생하는 것과는 거의 관련이 없습니다. 쉘이 입력을 기다리는 동안 터미널은비표준 입력 모드, 어떤 모드 라인 분야에서하지 마세요특수 문자를 특수하게 처리합니다. 쉘이 Ctrl+ D및 Ctrl+를 처리하는 방법 C은 전적으로 쉘이 사용하는 입력 편집 라이브러리(libedit, readline 또는 ZLE)와 해당 편집 라이브러리가 구성되는 방법(키 바인딩 등 사용)에 따라 달라집니다.
추가 읽기
- POSIX 터미널 인터페이스. 위키피디아.
답변2
CTRL+ C 는 인터럽트 신호이다. 명령이 중지됩니다.
CTRL+ D는 파일 끝이거나 . +를 exit()
입력하면 파일 끝으로 인해 명령이 종료됩니다. 쉘에 +를 입력하면 아무 일도 일어나지 않습니다. 그러나 +를 입력하면 대부분의 시스템에서 현재 쉘이 종료됩니다.CTRLDCTRLCCTRlD