수신자에 따라 ls 명령이 다르게 작동


12

lsstdout이 무엇인지 같은 명령을 어떻게 알 수 있습니까?

ls대상 stdout이 무엇인지에 따라 다르게 작동하는 것 같습니다 . 예를 들어 내가하는 경우 :

ls /home/matt/tmp 

결과는 다음과 같습니다.

a.txt b.txt c.txt

그러나 내가 할 경우

ls /home/matt/tmp | cat

결과는 (즉, 결과 당 줄 바꿈)입니다.

a.txt
b.txt
c.txt

프로세스에 stdout에 대한 파일 설명자 1이 전달 되었습니까? 결과 형식을 지정하는 방법을 어떻게 결정합니까? 파일 디스크립터가 정보를 공개합니까?


관련 unix.stackexchange.com/q/157285/4671 , unix.stackexchange.com/q/63108/4671 및 아마도 기타. 인기있는 주제 인 것 같습니다. 이것은 이들 중 하나의 속임수 일 수 있습니다.
Faheem Mitha

답변:


22

ls프로그램은 isatty()fd 1이 tty인지 아니면 다른 것 (파이프, 파일 등)인지 알기 위해 사용 합니다. 보낸 사람 man 3 isatty:

int isatty(int fd);

설명
isatty()함수 fd는 터미널을 참조하는 열린 파일 디스크립터 인지 테스트합니다.


Updade :ls.c coreutils에서 1538 행 (git 개정 43a987e1) :

  if (isatty (STDOUT_FILENO))
    {
      format = many_per_line;
      /* See description of qmark_funny_chars, above.  */
      qmark_funny_chars = true;
    }

( many_per_line자기 설명해야합니다.)


8

정확한 답변이 아니라 예시입니다. 배쉬 스크립트에서는 비슷한 효과를 얻을 수 있습니다 test/ [[의를 -t:

-t FD True if FD is opened on a terminal.

다음과 같이 사용하십시오.

bash-4.2$ where() { [[ -t 1 ]] && echo 'my output goes to TTY' || echo 'my output is redirected'; }

bash-4.2$ where
my output goes to TTY

bash-4.2$ where | cat
my output is redirected

bash-4.2$ where > test.file
bash-4.2$ cat test.file
my output is redirected

6

OpenBSD ls(1) 매뉴얼에서 :

기본적으로 ls는 표준 출력에 대한 라인 당 하나의 항목을 나열합니다. 터미널 또는 -C, -m 또는 -x 옵션이 지정된 경우는 예외입니다.

그런 다음 나중에

-1 (숫자``1 '') 출력은 한 줄에 한 항목 씩 강제합니다. 출력이 터미널에없는 경우의 기본값입니다.

[...]

-C 다중 열 출력을 강제합니다. 출력이 터미널로 출력 될 때의 기본값입니다.


1

명령을 ls사용하여 의사 터미널에서 실행 하고 다른 명령으로 script출력을 파이프 ls하고 stdout 스트림의 파이프가없는 것처럼, 즉 stdout이 터미널 (tty) 인 것처럼 동일한 출력 형식을 얻을 수 있습니다.

isatty()Stéphane Gimenez가 이미 지적한 기본 메커니즘에 대해서는 ls.c를 참조하십시오 .

ls -G /
ls -G / | cat
script -q /dev/null ls -G / | sed $'s/\r$//g' | cat

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