표준 출력 리디렉션은 개행 문자가 없는 행을 무시합니다.

표준 출력 리디렉션은 개행 문자가 없는 행을 무시합니다.

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내장 옵션을 사용할 수 있습니다 . 지적했다: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(...)

을 추가했는데 (...), 이는 두 번째 줄의 끝에서 끝나는 줄이 없다는 뜻입니다. 그러나 텍스트는 계속 처리되고 인쇄됩니다.

관련 정보