모든 출력이 터미널로 전달되는 것은 아닙니다.

모든 출력이 터미널로 전달되는 것은 아닙니다.

내가 아는 한, 잘 작동하는 명령줄 프로그램은 $TERM환경 변수를 확인하고, 터미널 에뮬레이터의 이름을 얻고, 데이터베이스에서 해당 항목을 찾은 terminfo다음 이러한 이스케이프 코드를 사용하여 색상, 글꼴과 같은 터미널 설정을 제어해야 합니다. , 스타일, 와이프 화면을 지우고 커서 위치를 설정합니다.

그러나 나는 게으른 프로그래머이므로 일부 텍스트를 녹색으로 만들고 싶다면 가장 쉬운 방법은 내 프로그램에 직접 ANSI 이스케이프 코드를 삽입하는 것입니다.

print("\033[32mhi\033[0m")

터미널 색상을 이렇게 변경하는 것은단순한구현을 통해 새로운 종속성(예: ncurses)을 배울 필요가 없고 외부 프로그램(예: ncurses )을 실행할 필요가 없으며 tput터미널 라이브러리가 있는 언어 대신 문자열이 있는 모든 언어로 프로그램을 작성할 수 있습니다. .

내 이상주의자는 특정 구현보다 표준에 의존하는 것이 항상 더 낫다고 믿습니다. 내 macOS 설치에는 2000개가 넘는 터미널 정의가 함께 제공됩니다 /usr/share/terminfo. 반면에 실용주의자들은 모두가 수년 동안 ANSI 코드를 내장해 왔으며 모든 것이 괜찮은 것 같다고 지적합니다.

$TERM헬퍼 라이브러리를 사용하지 않고 ANSI 코드를 직접 사용하는 코드나, 그 이외의 것인지만 확인하는 소프트웨어, dumb전혀 확인하지 않는 소프트웨어를 자주 봅니다 . $TERM이에 대해 불평하거나 다른 터미널 유형에 대한 지원을 요청하는 사람은 거의 없습니다.

그 외에도 인터넷에서 정말 많은 글을 봤고,언급되지 않은다른 터미널 유형이나 이스케이프 코드는 ANSI를 "터미널에서 굵게 및 색상을 만드는 방법"으로 설정합니다. 다른 모든 이스케이프 코드 세트는 사라진 것으로 보이며 ANSI 코드(또는 ECMA-48 코드 또는 VT102 코드)는 개발 커뮤니티에서 확립한 사실상의 표준이 되었습니다.

그래서 내 질문은: 2019년에 명령줄 소프트웨어를 작성한다면 ANSI를 사용하는 터미널에서만 사용될 것이라고 가정해도 안전합니까?


편집하다:사람들은 tputterminfo를 처리할 필요 없이 화면에 색상을 인쇄하기 위해 런타임에 이를 호출할 것을 제안합니다. 이는 효과가 있고 많은 경우에 좋은 솔루션이지만 제 생각에는 프로그램이 시작될 때 별도의 바이너리를 여러 번 실행해야 하기 때문에 불필요한 런타임 비용이 발생합니다.

답변1

질문을 올바르게 이해하면 실제로 의견이 나올까요? 고려해 볼 만한 몇 가지 사항을 요약해 보겠습니다.

모든 출력이 터미널로 전달되는 것은 아닙니다.

사소하게 들리겠지만, 세계의 모든 터미널이 ANSI 시퀀스를 올바르게 이해하더라도(다음 설명에 대한 주석에서 언급된 것과는 다릅니다)모두반례를 찾는 것만으로도 진술을 거부할 수 있습니다. grep출력이 파일이나 다른 프로그램(예: 대화형 사용 또는 스크립트 프로그램 호출)을 통해 리디렉션되는 두 가지 경우를 생각해 보세요.

이러한 경우 일반적으로 다음과 같은 출력을 원합니다.아니요취급을 단순화하기 위해 색상이 지정되었습니다. 이러한 경우 환경 변수에만 의존하는 것만으로 TERM는 충분하지 않습니다. 예를 들어 파이프라인을 대화형으로 입력할 수 있으며 이로 인해 TERM설정되었지만 바람직하지 않은 색상 출력이 발생합니다.

색상은 다를 수 있습니다

나는 원시 ANSI 시퀀스를 자체적으로 출력하는 스크립트를 꽤 많이 작성했습니다 TERM(보통 색상을 켜거나 끄는 옵션 포함). 다른 터미널 에뮬레이터, 셸 또는 동일한 터미널 에뮬레이터에 대한 옵션을 사용하면 종종 다른 색상으로 출력됩니다. 드물게(그러나 최신 Linux 시스템에 존재하며 찾을 수 있음) 인식 범위를 벗어난 색상(예: 검은색 바탕에 어두운 회색 등)도 발견됩니다. 때로는 녹색이어야 할 것에도 "줄이 그어진" 효과가 적용되는 경우가 있습니다.

"흥미로운 통찰력"을 얻으려면 많은 ANSI 이스케이프 시퀀스를 사용하는 모든 테스트와 무조건(즉, 독립적으로) 다음을 수행 TERM하고 rxvt마지막 gnome-terminal으로 xtermLinux 콘솔에서 실행합니다.

추상화 레이어 중 하나를 사용하지 않으면 대상 응용 프로그램이 이스케이프 시퀀스를 인식하고 처리할 수 있더라도 색상 지정이 실패할 가능성이 항상 있습니다.

결론적으로

2019년에는 원시 ANSI 이스케이프 시퀀스가 ​​예상대로 작동할 것이라고 가정하는 것이 완전히 안전하지는 않습니다.

응용 프로그램에 터미널 제어가 얼마나 중요한지 생각해 보세요. 중요하다면(색상/터미널 제어가 없으면 중요한 기능을 잃게 된다는 점에서) 원래 ANSI 이스케이프 시퀀스에 문제가 있는 것입니다. 위험이 너무 높습니다. 그다지 중요하지 않은 경우(예: 눈길을 끄는 로그, 화려한 대화형 메뉴 대 간단한 대화형 메뉴 등) 색상 출력에 대해 매우 제한된 추상화(예: 원시 ANSI 시퀀스 + 모두 끄는 옵션)를 사용하는 것이 합리적으로 보입니다. 색상)).

기타 상대화 진술

컬러 출력이나 기타 터미널 제어 시퀀스가 ​​필요한 동일한 응용 프로그램도 획득해야 하는 경우입력하다특별한 방법으로, ncurses나 좀 더 "현대적인" 솔루션과 같이 철저하게 개발된 솔루션을 찾아야 할 때입니다...

의견에서 지적했듯이 테스트된 환경만이 모든 소프트웨어에 대해 진정으로 안전합니다. 환경을 이해한다면 언제든지(일부 추상적인 "이식성"을 희생하더라도) 해당 환경에서 구현되는 프로그램에 가정을 추가할 수 있습니다.

마지막으로 프로그램은실제로 터미널 정보가 포함된 상위 레벨 라이브러리를 사용하는 것이 모든 경우에 안전하지는 않습니다. 색상은 구성된 터미널 색상 구성표에 따라 다르며 일부 효과(예: 밑줄)는 모든 터미널 및 글꼴 조합에서 작동하지 않습니다. 그런 다음 TERM"잘못된" 설정으로 인해 응용 프로그램이 실패하는 경우도 있습니다( tmux종종 실행 문제가 발생함 ssh).

답변2

OP에 동의합니다. 모든 실제적인 목적을 위해 ANSI가 아닌 터미널은 더 이상 사용되지 않습니다. 내 말을 믿을 수 없다면 2021년에 Wyse나 다른 비ANSI 터미널을 사용해 보세요(지금은). 내가 했던 것처럼 여러분도 실행 중인 프로그램이 ANSI 터미널을 "인식"하도록 하려면 "스크린"이나 다른 프로그램을 사용해야 한다는 사실을 곧 알게 될 것입니다.

ANSI가 아닌 터미널을 지원하는 데 들이는 노력도 낭비이며, 커뮤니티는 이 특정한 기술 부채를 정말로 버려야 합니다.

그러고 보니,연약한ANSI 구현에는 차이가 있으므로 잘 지원되는 명령을 고수하고 있는지 확인하기 위해 몇 가지 다른 터미널 에뮬레이터에서 프로그램을 시험해 보고 싶을 것입니다.

관련 정보