`echo -e“\\\ SOME_TEXT”가 왜 하나의 백 슬래시 만 표시합니까?


19

리눅스 쉘에서 문자 이스케이프 처리에서 어떤 일이 일어나고 있는지 설명 할 수 있습니까? 나는 무엇을 어떻게하는지 이해하는 데 성공하지 않고 다음을 시도하고 많은 것을 봤다.

root@sv01:~# echo -e "\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\\ Hello!"
\\\ Hello!
root@sv01:~# echo -e "\n Hello!"

 Hello!
root@sv01:~# echo -e "\\n Hello!"

 Hello!
root@sv01:~# echo -e "\\\n Hello!"
\n Hello!

나는 거기에서 완전히 잃어 버렸습니다. 예를 들어, 왜 세 개의 백 슬래시가 하나의 백 슬래시를 제공합니까? 나는 기대할 것입니다 : 첫 번째 두 개는 하나로 탈출 할 것이고, 세 번째는 탈출 할 것이 없으므로 슬래시 (첫 번째 실험에서 줄)로 남아 있지만 세 번째 것은 사라집니다.
왜 4에서 1 개의 백 슬래시가 발생 \\\\ Hello합니까? 각 쌍이 백 슬래시 하나-> 두 개의 백 슬래시를 줄 것으로 기대합니다.

그리고 왜 \ n 탈출하기 위해 마지막 경우에 세 개의 백 슬래시가 필요합니까? 그것을 얻기 위해 탈출의 배경에서 무슨 일이 일어나고 있습니까? \\n케이스 와 어떻게 다릅니 까?

이전 행에서 무슨 일이 일어나고 있는지에 대한 설명에 감사드립니다.


echo -e동작은 어쨌든 표준으로 정의되지 않습니다 . pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html을 참조하십시오 . 입력 어디에나 리터럴 백 슬래시가 있으면 출력이 완전히 구현 정의 되며 허용되는 유일한 옵션은 -n(표준 호환 구현이 echo -e출력 -e에 인쇄 됨을 의미 )입니다.
Charles Duffy

... 쉘이 bash인지 100 % 확신 하더라도 echo -e 안전하지 않습니다 : 런타임 옵션 과 런타임 옵션이 모두 활성화되어 있거나 동등한 빌드 타임 옵션으로 컴파일 된 경우 echo표준에 따라 동작합니다 . 안전한 방법은 대신 사용하는 것입니다. 위의 링크에서 APPLICATION USAGE 및 RATIONALE 섹션을 대신 하여 대체 기능을 수행 하는 방법을 설명하십시오 . posixxpg_echoprintfprintfecho
Charles Duffy

답변:


28

이 때문입니다 bashecho -e결합. 에서man 1 bash

따옴표가없는 백 슬래시 ( \)는 이스케이프 문자입니다. 다음을 제외한 다음 문자의 리터럴 값을 유지합니다 <newline>. […]

큰 따옴표 문자를 묶는 것은 제외하고, 따옴표 내의 모든 문자의 리터럴 값을 보존 $`,, \, [...] 백 슬래시는 다음 문자 중 하나 다음 만의 특별한 의미를 유지한다 : $`, ", \, 또는 <newline>.

요점은 : 큰 따옴표 역 슬래시가 항상 특별하지는 않습니다.

echo일반적으로 다양한 구현이 있으며 내장되어 있습니다 bash. 여기서 중요한 것은이 동작입니다.

경우에 -e적용되는, 다음의 시퀀스가 인식되어
\\
슬래시
[...]
\n
개행

이제 우리는 디코딩 할 수 있습니다 :

  1. echo -e "\ Hello!"-특별한 것도없고, 특별한 bash것도 없다 echo. \유지합니다.
  2. echo -e "\\ Hello!"– 첫 번째 \bash두 번째를 \문자 그대로 취급하라고 말합니다 . echo도착 \ Hello!이상 역할을합니다.
  3. echo -e "\\\ Hello!"– 첫 번째 \bash두 번째를 \문자 그대로 취급하라고 말합니다 . echo도착 \\ Hello!과 (때문에 -e)는 인식 \\으로 \.
  4. echo -e "\\\\ Hello!"– 첫 번째 \bash두 번째를 \문자 그대로 취급하라고 말합니다 . 세 번째는 네 번째에 대해 동일하게 말합니다. echo도착 \\ Hello!과 (때문에 -e)는 인식 \\으로 \.
  5. echo -e "\\\\\ Hello!"– 첫 번째 \bash두 번째를 \문자 그대로 취급하라고 말합니다 . 세 번째는 네 번째에 대해 동일하게 말합니다. 마지막 것은 특별하지 않습니다. echo를 가져 \\\ Hello!오고 (때문에 -e) 이니셜을 \\로 인식 \하고 마지막 \은 그대로 유지합니다.

등등. 보시다시피, 최대 4 개의 연속 백 슬래시가 결과를 제공합니다. 그렇기 때문에 3 개를 얻으려면 적어도 9 개가 필요합니다. 9 = 4 + 4 + 1.

지금과 \n:

  1. echo -e "\n Hello!"–에 특별한 것은 없습니다 bash. echo는 동일한 문자열을 가져오고 (때문에 -e) \n줄 바꿈으로 해석 합니다.
  2. echo -e "\\n Hello!"- bash해석 \\\; echo얻는 \n Hello!결과는 상기와 동일합니다.
  3. echo -e "\\\n Hello!"bash이니셜 \\\; echo\\n Hello!인해 인쇄해야하는 리터럴로 -e해석 \\됩니다 \.

결과는 (다른 행동 으로 인한) '대신에 또는 "다른 bash행동 으로 인해 -e(다른 echo행동으로) 달라질 수 있습니다.


1
대단히 감사합니다! bash가 수행하는 단계와 bash가 -e이미 판단한 텍스트 를 판단하는 두 번째 단계 가 있습니다. 그것이 맞으면 혼란을 제거합니다. 어떻게 sed행동하는지 언급 할 수 있습니까? 탈출 기술에 자체 빌드가 있습니까? 그래서 에코와 같이 행동 -e합니까?
Mohammed Noureldin

2
@MohammedNoureldin 네, 두 단계가 있습니다. 원래 질문은 그대로 유지됩니다 sed. 과 복잡하게 만들지 마십시오 . 그래도 다른 질문을 할 수도 있습니다 sed.
Kamil Maciorowski

3
@MohammedNoureldin sed은 동일한 기본 원칙을 따릅니다. bash는 규칙에 따라 명령 줄을 해석하고 따옴표와 이스케이프를 구문 분석 (및 제거) 할 수 있습니다. 그 결과는 전달됩니다 sed에 따라 해석하는 자사의 탈출 규칙. BTW,에서 따옴표로 묶은 bash해석을 수행하지 않기 때문에 (bash로) 작은 따옴표로 묶인 문자열을 사용하여이를 단순화 할 수 있습니다 .bash는 작은 따옴표를 제거하고 그 안에있는 것을 명령으로 직접 전달합니다.
Gordon Davisson

나는 여전히 작은 문제가 echo -e "\\\n Hello!"있습니다. 여기서 bash는 이스케이프 처리되고 \\n, -e결과가되며 결과로 나온 두 개의 백 슬래시를 빠져 나가게 \\n됩니다 \n. 이제 누가 \n그것을 새로운 줄로 해석 합니까? 일반적으로의 경우 echo -e "\n Hello!"bash는 아무 것도 수행하지 않고 줄 -e바꾸기 \n로 해석 합니다. 그러나 처음 언급 된 상황에서 해석을하기 전에 해석 프로세스가 수행되었습니다 \n. 그 점을 설명해 주시겠습니까?
모하메드 누 렐딘

1
내 잘못, 나는 그들의 밤과 함께 이틀 동안 그것에 대해 읽었고, 분명히 나는 ​​사건을 섞기 시작했다. 나는 sed어제 밤 나를 혼란스럽게하는 다른 것을 얻었을 것이라고 생각한다. 와 같은 다시 시도 echo -e하고 sed, 나는 제외, 덕분에 같은 일을있어!
Mohammed Noureldin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.