이와 같은 명령은 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