$'...', $"...", '...' 및 "..."를 사용한 텍스트 색상

$'...', $"...", '...' 및 "..."를 사용한 텍스트 색상

제가 기억하는 한, 저는 개인적으로 bash를 사용할 때 출력 텍스트의 색상을 변경하기 위해 다음 방법을 사용합니다.

red=$'\033[1;31m'                                                                        
nc=$'\033[0m'

echo "${red}This is red text$nc"

macOS에서 사용하든 Linux에서 사용하든 항상 제게는 효과적입니다. 호기심에서 이것이 왜 작동하는지 더 잘 이해하기 위해 조사를 한 결과 $( )가 포함되지 않은 몇 가지 red='\033[1;31m'답변/예를 찾았습니다. 몇 가지 테스트를 거친 후 를 사용하지 않으면 $출력 색상이 빨간색으로 변경되지 않고 문자열만 인쇄됩니다. 그러나 sh텍스트를 실행하는 대신 사용하면 bash텍스트의 색상이 변경됩니다 . 이것이 왜 그런지 이해하도록 도와줄 수 있는 사람이 있나요?

또한 작은 따옴표 대신 큰 따옴표를 사용하여 테스트했는데 사용한 경우에만 작동하는 것 같았습니다 sh. 아래에 예시를 게시하겠습니다.

내가 사용하는 스크립트와 코드는 다음과 같습니다.

#!/bin/bash                                                                              
                                                                                         
red=$'\033[1;31m'                                                                        
nc=$'\033[0m'                                                                            
                                                                                         
echo "${red}Test 1$nc"                                                                   
echo ""                                                                                  
                                                                                         
##########################                                                               
                                                                                         
red=$"\033[1;31m"                                                                        
nc=$"\033[0m"                                                                            
                                                                                         
echo "${red}Test 2$nc"                                                                   
echo ""                                                                                  
                                                                                         
##########################                                                               
                                                                                         
red='\033[1;31m'                                                                         
nc='\033[0m'                                                                             
                                                                                         
echo "${red}Test 3$nc"                                                                   
echo ""                                                                                  
                                                                                         
##########################                                                               
                                                                                         
red="\033[1;31m"                                                                         
nc="\033[0m"                                                                             
                                                                                         
echo "${red}Test 4$nc"                                                                   
echo ""  

bash 및 sh를 사용하여 macOS에서 출력:

여기에 이미지 설명을 입력하세요.

Linux에서 bash와 sh를 모두 사용한 결과:

여기에 이미지 설명을 입력하세요.

답변1

여기서 가장 중요한 것은 터미널이 제어 시퀀스를 인식하려면 터미널로 전송된 출력에 ESC 문자가 포함되어야 하며 [1;31mESC는 제어 문자이며 일반적으로 쉘 스크립트에서 있는 것처럼 표시하지 않는다는 것입니다. 그러나 \0338진수 문자 코드(10진수 27, 8진수 033 또는 16진수 0x1b)를 사용하여 문자를 나타내려면 백슬래시 이스케이프 문자를 사용하십시오. ). 나머지는 그냥 일반 캐릭터입니다.

이제 백슬래시 이스케이프 문자는 어느 시점에서 원래 ESC 문자로 변경되어야 합니다. 이런 일이 발생할 수 있는 두 곳이 있습니다: 변수에 대한 할당과 이를 인쇄하는 명령입니다.


이를 지원하는 쉘에서는 $'...'인용문 유형이 이미 이스케이프를 설명하므로 이후 red=$'\033[...'변수 자체에는 원래 ESC 문자가 포함됩니다. 이것은 표준 POSIX 기능이 아니며 이를 지원하지 않는 셸에서는 원시 달러 기호를 할당한 다음 백슬래시 033[등을 할당합니다. 반면, red='\033[...'백슬래시 033[등은 할당만 되며 이스케이프는 해석되지 않습니다. 바라보다

( $"...""..."이스케이프는 해석되어서는 안 되며 달러 기호가 있는 이스케이프도 비표준이므로 지원하지 않는 쉘에 문자 그대로 달러 기호를 남길 수 있습니다.)


그런 다음 두 번째 단계는 인쇄입니다. 백슬래시 이스케이프는 일부 쉘에서 echo확장됩니다 . 다른 경우에는 그렇지 않습니다. 그들 중 일부 echo -e도 마찬가지입니다 . Bash는 echo기본적으로 이 작업을 수행하지 않지만 설정을 사용하면 xpg_echo... 수행됩니다. Zsh는 echo이를 해석합니다. 바라보다


따라서 재고 Linux 데스크톱 배포판의 재고 Bash에서 xpg_echowhere가 설정되지 않은 경우 red=$'\033[1;31m'; echo "${red}text"작업에 ESC가 생성되고 빨간색 텍스트가 인쇄되지만 red='\033[1;31m'; echo "${red}text"작업이나 에서는 생성되지 않고 일반으로 인쇄 echo됩니다. \033[1;31mtext그림 물감.

Debian/Ubuntu에서는 shDash인데 $'...'따옴표는 지원하지 않지만 echo백슬래시는 해석되므로 red=$'\033[1;31m'; echo "${red}text"일반 색상이 인쇄된 $다음 빨간색 텍스트가 인쇄됩니다. 이것은 Linux를 실행했을 sh때의 모습 입니다. 일부 다른 Linux 시스템에서는 다른 결과를 얻을 수 있습니다.

Mac에서 설치된 셸은 sh실제로 설정된 Bash(설치 시 비활성화된 셸 xpg_echo)이거나 최신 macOS 버전의 zsh입니다. POSIX와 호환되도록 만들려는 bash초기 시도에도 불구하고sh그들은 아직도 지지한다quote $'...'이므로 둘 다 빨간색 텍스트를 red=$'\033[1;31m'; echo "${red}text"인쇄합니다 red='\033[1;31m'; echo "${red}text".


아직도 혼란스러워요? red='\033[1;31m'; printf "%b\n" "${red}text";모든 POSIX 유사 쉘에서 작동해야 합니다. 인수에서 백슬래시 이스케이프를 처리하도록 지시 %b하면 "텍스트"의 모든 내용이 처리됩니다.

답변2

리눅스 제가 대답할 수 있어요. 핵심은 ANSI 이스케이프 시퀀스를 사용하는 방법이 아니라 변수를 선언하는 방법이라고 생각합니다.

red=$'\033[1;31m'  # a dollar sign and an ANSI escape sequence

red=$"\033[1;31m"  # a dollar sign and an ANSI escape sequence

red='\033[1;31m'  # only an ANSI escape sequence

red="\033[1;31m"  # only an ANSI escape sequence

에서 sh인쇄할 때

echo "${red}some text"

변수 값을 인쇄 red한 다음 일부 텍스트를 인쇄합니다. 처음 두 경우에는 ANSI 이스케이프 시퀀스 앞에 달러 기호가 있으므로 색상 변경의 영향을 받지 않습니다.

에서 bash인쇄할 때

echo -e "${red}some text"

ANSI 이스케이프 시퀀스는 해석되지만

echo "${red}some text"

ANSI 이스케이프 시퀀스는 해석되지 않지만 문자는 문자 그대로 인쇄되지만 명령문 "앞에" 변환이 수행될 수 있습니다 echo.

options 없이 ANSI 이스케이프 시퀀스를 해석할 수 있는 sh또 다른 내장 함수가 있습니다 .echo-e

bash첫 번째 예와 다른 예의 차이점은 16진수 값을 보면 알 수 있습니다 red. 제가 편집한 스크립트를 확인해보세요.

#!/bin/bash

red=$'\033[1;31m'
nc=$'\033[0m'
hexdump <<< "$red"
echo $1 "${red}Test 1$nc"
echo ""

##########################

red=$"\033[1;31m"
nc=$"\033[0m"
hexdump <<< "$red"
echo $1 "${red}Test 2$nc"
echo ""

##########################

red='\033[1;31m'
nc='\033[0m'
hexdump <<< "$red"
echo $1 "${red}Test 3$nc"
echo ""

##########################

red="\033[1;31m"
nc="\033[0m"
hexdump <<< "$red"
echo $1 "${red}Test 4$nc"
echo ""

echo -e또한 해당 옵션을 스크립트에 추가하여 보기 쉽게 만들었으므로 두 가지를 모두 시도해 보세요.

bash box2

그리고

bash box2 -e

예를 들어 달러 기호 없이 "coloring" 변수를 선언하는 것이 좋습니다.

red='\033[1;31m'

달러 기호를 사용하는 경우에만사용예를 들어 echo문의 변수입니다.

관련 정보