내가 아는 한, 잘 작동하는 명령줄 프로그램은 $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를 사용하는 터미널에서만 사용될 것이라고 가정해도 안전합니까?
편집하다:사람들은 tput
terminfo를 처리할 필요 없이 화면에 색상을 인쇄하기 위해 런타임에 이를 호출할 것을 제안합니다. 이는 효과가 있고 많은 경우에 좋은 솔루션이지만 제 생각에는 프로그램이 시작될 때 별도의 바이너리를 여러 번 실행해야 하기 때문에 불필요한 런타임 비용이 발생합니다.
답변1
질문을 올바르게 이해하면 실제로 의견이 나올까요? 고려해 볼 만한 몇 가지 사항을 요약해 보겠습니다.
모든 출력이 터미널로 전달되는 것은 아닙니다.
사소하게 들리겠지만, 세계의 모든 터미널이 ANSI 시퀀스를 올바르게 이해하더라도(다음 설명에 대한 주석에서 언급된 것과는 다릅니다)모두반례를 찾는 것만으로도 진술을 거부할 수 있습니다. grep
출력이 파일이나 다른 프로그램(예: 대화형 사용 또는 스크립트 프로그램 호출)을 통해 리디렉션되는 두 가지 경우를 생각해 보세요.
이러한 경우 일반적으로 다음과 같은 출력을 원합니다.아니요취급을 단순화하기 위해 색상이 지정되었습니다. 이러한 경우 환경 변수에만 의존하는 것만으로 TERM
는 충분하지 않습니다. 예를 들어 파이프라인을 대화형으로 입력할 수 있으며 이로 인해 TERM
설정되었지만 바람직하지 않은 색상 출력이 발생합니다.
색상은 다를 수 있습니다
나는 원시 ANSI 시퀀스를 자체적으로 출력하는 스크립트를 꽤 많이 작성했습니다 TERM
(보통 색상을 켜거나 끄는 옵션 포함). 다른 터미널 에뮬레이터, 셸 또는 동일한 터미널 에뮬레이터에 대한 옵션을 사용하면 종종 다른 색상으로 출력됩니다. 드물게(그러나 최신 Linux 시스템에 존재하며 찾을 수 있음) 인식 범위를 벗어난 색상(예: 검은색 바탕에 어두운 회색 등)도 발견됩니다. 때로는 녹색이어야 할 것에도 "줄이 그어진" 효과가 적용되는 경우가 있습니다.
"흥미로운 통찰력"을 얻으려면 많은 ANSI 이스케이프 시퀀스를 사용하는 모든 테스트와 무조건(즉, 독립적으로) 다음을 수행 TERM
하고 rxvt
마지막 gnome-terminal
으로 xterm
Linux 콘솔에서 실행합니다.
추상화 레이어 중 하나를 사용하지 않으면 대상 응용 프로그램이 이스케이프 시퀀스를 인식하고 처리할 수 있더라도 색상 지정이 실패할 가능성이 항상 있습니다.
결론적으로
2019년에는 원시 ANSI 이스케이프 시퀀스가 예상대로 작동할 것이라고 가정하는 것이 완전히 안전하지는 않습니다.
응용 프로그램에 터미널 제어가 얼마나 중요한지 생각해 보세요. 중요하다면(색상/터미널 제어가 없으면 중요한 기능을 잃게 된다는 점에서) 원래 ANSI 이스케이프 시퀀스에 문제가 있는 것입니다. 위험이 너무 높습니다. 그다지 중요하지 않은 경우(예: 눈길을 끄는 로그, 화려한 대화형 메뉴 대 간단한 대화형 메뉴 등) 색상 출력에 대해 매우 제한된 추상화(예: 원시 ANSI 시퀀스 + 모두 끄는 옵션)를 사용하는 것이 합리적으로 보입니다. 색상)).
기타 상대화 진술
컬러 출력이나 기타 터미널 제어 시퀀스가 필요한 동일한 응용 프로그램도 획득해야 하는 경우입력하다특별한 방법으로, ncurses나 좀 더 "현대적인" 솔루션과 같이 철저하게 개발된 솔루션을 찾아야 할 때입니다...
의견에서 지적했듯이 테스트된 환경만이 모든 소프트웨어에 대해 진정으로 안전합니다. 환경을 이해한다면 언제든지(일부 추상적인 "이식성"을 희생하더라도) 해당 환경에서 구현되는 프로그램에 가정을 추가할 수 있습니다.
마지막으로 프로그램은예실제로 터미널 정보가 포함된 상위 레벨 라이브러리를 사용하는 것이 모든 경우에 안전하지는 않습니다. 색상은 구성된 터미널 색상 구성표에 따라 다르며 일부 효과(예: 밑줄)는 모든 터미널 및 글꼴 조합에서 작동하지 않습니다. 그런 다음 TERM
"잘못된" 설정으로 인해 응용 프로그램이 실패하는 경우도 있습니다( tmux
종종 실행 문제가 발생함 ssh
).
답변2
OP에 동의합니다. 모든 실제적인 목적을 위해 ANSI가 아닌 터미널은 더 이상 사용되지 않습니다. 내 말을 믿을 수 없다면 2021년에 Wyse나 다른 비ANSI 터미널을 사용해 보세요(지금은). 내가 했던 것처럼 여러분도 실행 중인 프로그램이 ANSI 터미널을 "인식"하도록 하려면 "스크린"이나 다른 프로그램을 사용해야 한다는 사실을 곧 알게 될 것입니다.
ANSI가 아닌 터미널을 지원하는 데 들이는 노력도 낭비이며, 커뮤니티는 이 특정한 기술 부채를 정말로 버려야 합니다.
그러고 보니,연약한ANSI 구현에는 차이가 있으므로 잘 지원되는 명령을 고수하고 있는지 확인하기 위해 몇 가지 다른 터미널 에뮬레이터에서 프로그램을 시험해 보고 싶을 것입니다.