curl의 출력이 grep로 잘 색칠 할 수 없을 때의 대처

3059 단어 grep
grep 로 패턴 매치 하는 부분에 색을 칠하고 싶지만, 잘 되지 않았기 때문에 조사했을 때의 메모.

결론부터 말하자면 CR이 문제의 트리거이기 때문에 curl의 출력에 한하지 않았다.

증상



curl 의 결과를 출력하면서 Server 헤더에 주목해 보고 싶으므로, Server 의 부분에 색을 붙이고 싶다.
$ curl -s -D - google.co.jp | grep --color=auto -E '^|Server:'



위는 잘 작동합니다.

색칠을 줄 끝까지 만들려면 정규식에 .* 를 추가합니다.
$ curl -s -D - google.co.jp | grep --color=auto -E '^|Server:.*'



색이 붙어 있다고 생각했는데, 보이지 않게 되어 버렸다.

조사



hexdump로 살펴보자.
$ curl -s -D - google.co.jp | grep --color=auto -E '^|Server:.*' | hexdump -C



서버: 행이 존재하지만 이스케이프 시퀀스가 ​​보이지 않습니다.grep --color=auto 의 경우는 출력처가 제어 단말이 아니면 자동적으로 색칠을 해제하는 것 같다.
--color=always 에서 보자.
$ curl -s -D - google.co.jp | grep --color=always -E '^|Server:.*' | hexdump -C



서버: 혹은 이스케이프 시퀀스도 있는 것 같기 때문에, 표시할 때 뭔가 잘 되지 않는 것 같다.

좀 보기 힘들기 때문에 strace 의 write(2) 쪽을 확인한다.
## strace の出力先はファイルにする
## 端末に出そうとするとエスケープシーケンスが効いてしまうので注意
$ curl -s -D - google.co.jp | strace -y -o trace.txt -e write grep --color=auto -E '^|Server:.*'
$ grep "Server:" trace.txt
write(1</dev/pts/2>, "\33[01;31m\33[KServer: gws\r\33[m\33[K\n", 30) = 30
<ESC>[K 는 Erase in Line 로, 현재 위치로부터 행말까지를 소거하는 것 같다.Server: gws 는 착색되어 있지만, Carriege Return 으로 행두로 날아간 후 Erase in Line 로 지워져 개행되기 때문에, 표시되지 않게 되었다.

해결 방법



그래서 \r를 sed 등으로 제거한 다음 grep에 걸면 해결한다.
$ curl -s -D - google.co.jp | sed 's/\r//g' | grep --color=auto -E '^|Server:.*'



또, 구그하면 grep 의 환경 변수로의 해결책도 발견한다.
GREP_COLORS="ne" 로 하여 Erase in Line 을 추가하지 않게 하고 있다.
$ curl -s -D - google.co.jp | GREP_COLORS="ne" grep --color=auto -E '^|Server:.*'

좋은 웹페이지 즐겨찾기