ls 명령의 동작은 수신자에 따라 다릅니다.

ls 명령의 동작은 수신자에 따라 다릅니다.

이와 같은 명령은 ls표준 출력이 무엇인지 어떻게 알 수 있습니까?

ls대상 표준 출력에 따라 동작이 다른 것 같습니다. 예를 들어, 이렇게 하면:

ls /home/matt/tmp 

결과 :

a.txt b.txt c.txt

하지만 만약 내가 그렇게 한다면

ls /home/matt/tmp | cat

결과는 다음과 같습니다(즉, 각 결과는 새 줄을 바꿉니다).

a.txt
b.txt
c.txt

프로세스에는 stdout에 대한 파일 설명자 1이 전달됩니다. 그렇죠? 결과 형식을 지정하는 방법은 어떻게 결정됩니까? 파일 설명자가 정보를 유출합니까?

답변1

이 프로그램은 fd 1이 tty인지 아니면 다른 것(파이프, 파일 등...)인지 확인하는 ls데 사용됩니다 . isatty()에서 man 3 isatty:

int isatty(int fd);

설명
isatty()함수는 fd열린 파일 설명자가 터미널을 참조하는지 여부를 테스트합니다.


고쳐 쓰다:coreutils의 라인 1538 ls.c(git 개정 43a987e1):

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

( many_per_line자체 설명이 있어야 합니다.)

답변2

정확한 답변은 아니지만 예시입니다. Bash 스크립트에서는 test/achieve를 사용하여 비슷한 [[효과를 얻을 수 있습니다 -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

답변3

OpenBSD에서ls(1) 수동:

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

그런 다음 나중에:

-1(숫자 "1".) 출력은 한 줄에 하나의 항목으로 강제됩니다. 출력이 터미널로 진행되지 않을 때의 기본값입니다.

[...]

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

답변4

이 명령을 사용 하여 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

관련 정보