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
.
버그 수정은 매우 감사할 것이며 이 질문에 인용된 답변을 연결하겠습니다.
Giles가 지적했듯이 전체 솔루션은 완벽하지 않습니다. 읽기, 표준입력, 진행 표시줄에 문제가 있습니다. 할 수도 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을 사용하는 등 다른 작업을 수행해야 합니다. 이것은 인쇄될 것입니다 ( . 와 달리 Perl은 마지막 개행을 구체적으로 처리하지 않기 때문에 <foo><bar\n>
마지막 개행 앞에 개행이 있습니다 . 색상 지정과는 아무 관련이 없습니다.)>
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(...)
을 추가했는데 (...)
, 이는 두 번째 줄의 끝에서 끝나는 줄이 없다는 뜻입니다. 그러나 텍스트는 계속 처리되고 인쇄됩니다.