적은 file1 file2 | 고양이 — 왜 작동합니까?


21

uss less file1 file2를 사용하면 "less buffer viewer"에 두 파일이 표시되지만 less file1 file2 | catstdout에 추가 된 두 파일의 내용을 인쇄합니다. 그것이 "더 적은 버퍼 뷰어"를 보여 주거나 다음 명령을 위해 stdout에 출력을 생성해야하는지 어떻게 알 수 있습니까? 이를 위해 어떤 메커니즘이 사용됩니까?

답변:


30

less텍스트를 표준 출력으로 인쇄합니다. 표준 외출

  • (A)에 단자 (/ 디바이스 / TTY?)하고, 기본 버퍼 뷰어를 연다
  • 스루 파이프를 사용하여 다른 programm에로 배관 할 때 | ( less text | cut -d: -f1)
  • > ( ) 로 파일 을 리디렉션 할 때 파일로less text > tmp

"isa tty " 라는 C 함수가 있는데,이 함수 는 출력이 tty (4.81, main.c, 112 행 이하)로 가는지 확인합니다. 그렇다면 버퍼 뷰어를 사용하고 그렇지 않으면처럼 동작 cat합니다.

bash에서는 test를 사용할 수 있습니다 (참조 man test)

  • -t FD 파일 디스크립터 FD가 터미널에서 열립니다.
  • -p FILE이 존재하며 명명 된 파이프입니다.

예:

[[ -t 1 ]] && \
    echo 'STDOUT is attached to TTY'

[[ -p /dev/stdout ]] && \
    echo 'STDOUT is attached to a pipe'

[[ ! -t 1 && ! -p /dev/stdout ]] && \
    echo 'STDOUT is attached to a redirection'

1
@tfh STDOUT이 파이프 또는 리디렉션에 연결되지 않은 경우 STDOUT이 파이프 또는 리디렉션에 연결되어 있는지 인쇄하지 않는 것이 맞습니다. 세 가지를 모두 스크립트에 넣으십시오. 전화는 bash script.sh, bash script.sh | cat, bash script.sh > file, 당신이 무엇을 얻을 출력을 참조하십시오.
hvd

1
stdout"파일에 쓸 수있는"것이 아닙니다. 당신이 write() 하는 일 입니다. less출력이 파일, 파이프, 소켓 또는 블록 장치인지 여부에 따라 다르게 수행하지 않아도됩니다. 그것은 tty가 아니라는 것만 중요하므로 그냥 동작 cat합니다. (나는 당신이 이것을 알고 있고 그것을 설명하기 위해 잘못된 단어를 선택했다고 가정하지만, 나는 이것을 다른 독자들에게 지적 할 것이라고 생각했습니다).
Peter Cordes

그래서 당신은 내 특정 질문에서 고양이처럼 행동하는 것이 덜 중요하다는 것을 의미합니다. 또는 더 일반적으로는 파이프 라인의 다음 명령처럼 행동합니다. 내가 이해 한 바에 따르면 정확히 동일한 동작이 다른 도구로 구현되었다고 가정 할 수 없습니다.
tfh December

@tfh : 아니요, 다음에 less나오는 "그림"을 찾지 않습니다 cat. catstdout이 tty가 아닌 경우 다음에 무엇이든 상관없이 작동 합니다.
Peter Cordes

@ MichaelD. : 고마워, 내 대답을 수정했다. 방금 lessTCGETS 하나를 사용하여 터미널 크기를 얻거나 tty가 아니라는 것을 알았지 만 분명히 잘못 추측했습니다.
Peter Cordes

6

lessstdout터미널 인지 확인하고 그렇지 않은 경우 처럼 동작합니다 cat(EOF까지 stdin을 stdout에 복사합니다).

이 기능을 사용하면 항상 출력 (예 : --help출력)을 보내면서 less파일로 쉽게 리디렉션 할 수있는 스크립트 나 프로그램을 작성할 수 있습니다 . some_command --fullhelp > help.txtstdin의 스페이스 바가 텍스트 등을 통해 페이지를 넘길 때까지 기다리면 짜증이납니다 . 일부 명령 (예 :) man은 자체 출력을 확인하여 호출기를 통해 출력을 보낼지 여부를 결정합니다. 을 실행하면을 (를) man ls > ls.txt호출하지 않습니다 $PAGER.

less파이프 라인에 스테이지를 더 추가 할 때 하나의 라이너에서 편집하는 것을 잊어 버린 경우 고양이 같은 동작이 편리합니다.


less터미널 크기 (화면 크기, 한 번에 몇 줄을 표시할지 알기 위해)를 알아야합니다. 는 ioctl(2)그것의 사용 stdout어쨌든 비 터미널의 경우를 처리 피할 수 있도록, 비 터미널에 ENOTTY를 반환합니다. less실제로 isatty(3)터미널 크기를 확인하기 전에 사용 하지만 isattytty 전용 ioctl을 시도하고 오류가 없는지 확인하여 작동합니다.

more(1)(최소한 util-linux 버전 과 같은) 간단한 호출기 조차도이 기능을 가지고 있습니다. 왜냐하면 아마도이 경우를 위해 구현하는 가장 단순한 제정신 행동 일 것입니다.


무언가 less (예를 들어 grep foo bar.txt | less)에 파이프 할 때 /dev/tty키보드 입력 을 위해 열어야 합니다. (로이 작업을 수행하는 것을 볼 수 있습니다 echo foo | strace less).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.