쉘에 주어진 각 명령을 어떻게 파이프합니까?


14

쉘에서 실행되는 모든 명령이 다음과 같이 파이프로 연결되도록 .bashrc를 편집하고 싶습니다.

 $ sudo apt update
  _________________
< sudo apt update >
 -----------------
    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||

다소 비슷한 것을 관리했지만 완전히는 아닙니다.

$ bash
$ exec > >(cowsay)
$ echo "Hello AU!"
$ exit
 _______
< Hello AU! >
 -------
    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||

현재 쉘을 종료 한 후에 만 ​​발생하므로 원하는 결과가 아닙니다.

주로 재미 / 학습 목적입니다.


-n플래그를 사용하면 cowsay유용합니다. 공백을 보존합니다.
wjandrea 2016 년

답변:


12

방법을 약간 조정할 수 있습니다. cowsay직접 파이핑하는 대신 구분 문자까지 출력을 읽고 출력을로 보낸 cowsay후 모든 명령 후에 해당 문자를 인쇄하십시오.

exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
PROMPT_COMMAND='printf "\0"'

여기서는 ASCII NUL 문자를 사용하고 있습니다. 명령 출력에 나타나지 않을 다른 것을 사용할 수 있습니다.

프롬프트가 표시되면 출력이 나빠집니다.

$ export LC_ALL=C
$ exec > >(while IFS= read -d '' -r line; do if [[ -n $line ]]; then echo; printf "%s\n" "$line" | cowsay; fi; done)
$ PROMPT_COMMAND='printf "\0"'
$ ls
$
 ______________________________________
/ Desktop Documents Downloads Music    \
| Pictures Public Templates Videos
\ examples.desktop                     /
 --------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

$ echo foo
$
 ______
< foo  >
 ------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

이렇게하면 복잡한 출력을 시도하거나 텍스트 사용자 인터페이스 (명령 줄 편집기, 호출기 등)가있는 모든 명령이 중단됩니다.

이미 알고있는 것으로 가정하면 exec > >(...)프로세스 대체 부분은 다음과 같습니다.

  • while IFS= read -d '' -r line; do ... done: ASCII NUL 문자로 구분 된 데이터를 읽는 데 매우 일반적인 관용구입니다.

    • IFS= IFS를 빈 문자열로 설정하여 필드 분할을 비활성화합니다.
    • -r입력을 특수하게 read처리 하지 않도록합니다 \( \n예를 들어, \n개행 문자로 읽히고 변환되지 않음).
    • -d ''readNUL 문자까지 읽을 수 있는 방법입니다

    따라서 모든 것은 입력 내용을 최대한 유지하면서 NUL로 구분 된 섹션에서 입력을 반복합니다.

  • if [[ -n $line ]]; then ... fi; done -지금까지 읽은 입력이 비어 있지 않은 경우에만 작동합니다.
  • echo; printf "%s\n" "$line" | cowsay;-선행 빈 줄을 인쇄하여 cowsay 출력이 프롬프트와 충돌하지 않도록 입력 한 값을 cowsay로 보냅니다. printf보다 신뢰할 수 있고 안전합니다 echo.

1
내 프롬프트에 줄 바꿈이 있으면 cowsay 출력 두 번째 부분과 충돌합니다. 프롬프트를 방해하지 않는 것으로 설정합니까?
디저트

16

trapbash의 DEBUG신호를 남용 할 수 있고 남용합니다 .

trap 'bash -c "$BASH_COMMAND" | cowsay' DEBUG

예제 실행

$ trap 'bash -c "$BASH_COMMAND" | cowsay' DEBUG
$ echo "AU is awesome!"
 __________________
< AU is awesome! >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
AU is awesome!

그러나 이후에도 여전히 명령을 실행합니다. ilkkachu 덕분에 그 길을 찾았습니다.

$ shopt -s extdebug
$ trap 'bash -c "$BASH_COMMAND" | cowsay; false' DEBUG
$ echo "AU is awesome!"
 __________________
< AU is awesome! >
 ------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.