stdout 리디렉션은 개행 문자가 없는 줄을 무시합니다.

stdout 리디렉션은 개행 문자가 없는 줄을 무시합니다.

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옵션을 사용할 수 있습니다 . 다음과 같이 말합니다.readman 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이 없다는 의미입니다. 그러나 텍스트는 여전히 처리되고 인쇄됩니다.

관련 정보