stderr
터미널에서 빨간색으로 인쇄 하려고 합니다 . 아래 스크립트는 디버그 트랩 시 2
사용자 정의로 리디렉션합니다.8
exec 9>&2
exec 8> >(
while IFS='' read -r line || [ -n "$line" ]; do
echo -e "${RED}${line}${COLORRESET}"
done
)
function undirect(){ exec 2>&9; } # reset to original 9 (==2)
function redirect(){ exec 2>&8; } # set to custom 8
trap "redirect;" DEBUG
PROMPT_COMMAND='undirect;'
그것은에서 온다여기, 명확한 설명과 함께.
매우 잘 작동하는 것 같지만 개행 문자로 끝나지 않는 입력은 전혀 인쇄되지 않습니다. 저자 인용복음다시:
bash> echo -en "hi\n" 1>&2
hi <-- this is red
bash> echo -en "hi" 1>&2
bash> echo -en "hi" 1>&2
bash> echo -en "hi\n" 1>&2
hihihi <-- this is red
이유를 알 수 없습니다. 개행이 아닌 내용은 일종의 버퍼에 있는 것 같습니다. 파일 설명자에 도달하지도 못하거나 8
어떻게든 즉시 인쇄되기를 원하지 않습니다. 어디로 가나요? redirect
매번 제대로 호출됩니다. 또한 IFS=''
구분 기호가 없다는 의미이므로 에코 아웃이 8
줄 단위로 발생하는 이유를 잘 이해할 수 없습니다.
버그를 수정해 주시면 감사하겠습니다. 인용된 답변을 이 질문에 연결했습니다.
Gilles가 지적한 것처럼 이 전체 솔루션은 완벽하지 않습니다. 읽기, 표준 입력, 진행률 표시 su
줄 에 문제가 있습니다 source
. 그리고 파이프 파손이나 예상치 못한 터미널 종료와 같은 주요 문제가 자주 발생합니다. 누구든지 내 링크를 통해 여기에 도달했다면 사용을 고려해 보세요.https://github.com/sickill/stderred대신에 훨씬 더 좋습니다(아직 문제는 없습니다)(그러나 echo bla >&2
여전히 빨간색이 아니고해당 문제가 종료되었습니다)
답변1
줄 바꿈이 인쇄된 지점에서 동일한 줄의 일부로 부분 줄 출력을 얻었습니다. 라인의 일부는 내에서 버퍼링됩니다 read
.그게 하는 일이야:
그만큼읽다유틸리티는 표준 입력에서 단일 논리 라인을 읽어야 합니다.
예를 들어 이것은 <foobar>
1초 후에 인쇄되는 것이지 가 아닙니다 <foo><bar>
.
(echo -n foo ; sleep 1 ; echo bar) | (read x ; echo "<$x>")
전체 행보다 작은 부분에서 입력을 포착하려면 Perl을 사용하는 등 다른 작업을 수행해야 합니다. 이것은 인쇄될 것입니다 <foo><bar\n>
(마지막 과 달리 Perl은 마지막 개행을 특별히 처리하지 않기 >
때문에 마지막 개행 앞에 새 줄을 사용합니다. 색상 지정에는 문제가 되지 않습니다.)read
(echo -n foo ; sleep 1 ; echo bar) |
perl -e '$|=1; while(sysread STDIN,$a,9999) { print "<$a>"}'
환경에 내보낸 색상( RED
및 ) 에 대한 제어 코드가 있는 경우 다음과 같이 Perl 스크립트에서 이를 사용할 수 있습니다.COLORRESET
perl -e '$|=1; while(sysread STDIN,$a,9999) {print "$ENV{RED}$a$ENV{COLORRESET}"}'
답변2
Bash에서는 줄 끝 기호를 정의하는 내장 -d
옵션을 사용할 수 있습니다 . 다음과 같이 말합니다.read
man bash
-d delim The first character of delim is used to terminate the input line,
rather than newline.
정의되지 않은 경우 문자열을 한 줄로 간주하기 위해 나타날 때 read
까지 기다립니다 . \n
하지만 옵션을 사용하면 구분자로 -d
설정할 수 있습니다 . NUL
물론 입력을 NUL로 종료해야 합니다.
예:
printf "%s\0" $'x\n' y z | while IFS='' read -r -d $'\0' line
do
printf "%s\n" "$line"
done
산출:
x
y
z
다시 한 번 말하지만 이제 루프 printf
내부 는 .while
\n
printf "%s\0" $'x\n' y z | while IFS='' read -r -d $'\0' line
do
printf "%s" "$line"
done
산출:
x
yz(...)
를 추가했는데 (...)
이는 두 번째 줄 끝에 End-Of-Line이 없다는 의미입니다. 그러나 텍스트는 여전히 처리되고 인쇄됩니다.