특수 문자를 일반적인 문자로 사용하는 방법은 무엇입니까?


13

'큰 따옴표 문자 ( ")를 입력하는 방법'과 같은 많은 질문이 있습니까? 요청을 받고 있으며, 우리는 같은 대답 (로 입력 우리 사회를 혼란하지 않으려 \"로 묶여있는 경우 ', S "로 묶여있는 경우 '의.) 그래서, 문제는 여기에있다.

일반 문자와 같이 터미널에 특수 문자를 입력 할 수 없습니다. 예를 들어이 명령은 실패합니다.

echo Updates (11)

그렇다면 터미널 에이 문자를 일반적인 문자처럼 입력하는 방법은 무엇입니까?

!#$^&*?[](){}<>~;'"\|<space><tab><newline>

캐리지 리턴 이 특별한 곳을 아는 유닉스 쉘은 없습니다 . =, @그리고 %어떤 상황에서 어떤 껍질에 특별하다.
— Stéphane Chazelas

@ StéphaneChazelas Umm ... 캐리지 리턴 ( ^M)은 ^J나에게 줄 바꿈 ( ) 과 같은 역할 을합니다 (Ubuntu 14.04, sh).
— EKons

아니, 터미널 드라이버 변환 ^M에 ^J입력에하지만 ^M쉘에 특별하지 않고 인용 필요하지 않습니다. 입력 echo ^V^M | hd하면 0d 문자 (0a가 에코로 추가됨)가 표시됩니다.
— Stéphane Chazelas

@ StéphaneChazelas Umm ... 나는 무엇인지 모르겠다 hd. 아마도 xxd16 진수 뷰어로 더 낫다.
— EKons

어느 쪽이든 POSIX od -tx1또는 sed -n lvim의 xxd가 없으면를 사용하십시오 hd. 일부 시스템은 또한이 cat -vte나cat -A
— 스테판 Chazelas가에게

답변:


26

그것은 껍질에 달려 있습니다. 자세한 내용은 쉘 설명서를 확인하십시오.

또한 일부 문자는 일부 상황에서만 특별합니다. 예를 들어, 대부분의 쉘에서, *그리고 ?POSIX 나에 CSH 같은 쉘, 목록 컨텍스트에서만 특별 ~같은 일부 문자를 다음 단어의 시작 또는에서만 특별하다 :. 대한 동일 =에서 zsh. 일부 쉘에서는 [a와 일치 할 때 (일부 제한 사항이있는 경우)에만 특별합니다 ].

bash또는 과 같은 일부 쉘에서는 yash공백 토큰 구분 기호와 같은 특수 문자도 로케일에 따라 다릅니다.

인용 문자 (해당 문자의 특수 의미를 제거하기 위해)도 쉘마다 크게 다릅니다.

본 같은 껍질

Bourne과 같은 쉘 ( sh80 년대 이후 일부 시스템 또는 다른 시스템에서 호출 된 것으로 알려진 쉘)에 대한 요약 :

본 쉘

특수 문자:

  • "\'&|;()^`<>$, space, newline 및 tab은 인용되지 않은 간단한 명령 행에서 특별합니다.
  • #(초기 버전 제외)는 줄의 시작 부분이나 인용 부호가없는 공백, 탭 또는 뒤에 나오는 특수 문자 &|()^<>;`입니다.
  • {그리고 }그들은 쉘 키워드 (명령 위치에서 너무 만 단어)입니다 만 특별한에 있습니다.
  • *?[globbing 연산자처럼 특별하므로 목록 컨텍스트에서만 가능합니다. 의 경우 [, 그건 [...]그이 글 로빙 연산자, 하나 [또는 ]단지 특별한 의미를 제거하기 위해 인용 될 필요가있다.
  • =할당 연산자로 취급되는 상황에서는 특별합니다. 즉, 간단한 명령으로 인수를 따르지 않는 모든 단어에 대해 (after 제외 set -k)입니다.

인용 연산자

  • \개행을 제외한 모든 특수 문자를 인용합니다 ( 다음 실제 행 에 \<newline>긴 논리 행 을 계속하여 순서가 제거됨). 백틱 (backticks) 은 그 안에있는 것처럼 추가적인 복잡성을 추가하며, 닫는 백틱 (backtick)을 피하고 파서를 돕는 데 먼저 사용됩니다. 큰 따옴표 내부, 단지 자신을 탈출하기 위해 사용될 수있다, , 과 ( 여전히 줄 연속이다). here를 제외하고는 여기 문서 내부에 있습니다 . 이 문서 내에서 문자를 이스케이프 처리하는 유일한 방법입니다.\\"$`\<newline>"\
  • "..."큰 따옴표는 모든 문자를 제외하고 자체 \, $및 `.
  • '...' 작은 따옴표는 모든 문자를 제외한 모든 문자를 이스케이프합니다.

POSIX 쉘

POSIX 쉘은 다음을 제외하고 대부분 Bourne 쉘과 유사하게 작동합니다.

  • ^ 더 이상 특별한 성격이 아닙니다
  • ~어떤 상황 에서는 특별하다
  • { 특별 할 수 있으므로 인용해야합니다.

ksh

POSIX와 같은 것을 제외하고 :

  • {string}문자열에 따옴표가없는 경우 ,(또는 ..경우에 따라 버전 이있는 경우) 특별합니다 .
  • ksh93에는 $'...'복잡한 규칙을 가진 특별한 인용 연산자가 있습니다. 즉, 오퍼레이터로도 (일부 변형하여) 발견 bash, zsh, mksh와 FreeBSD 및 비지 sh.
  • ksh93또한 문자열에 현지화가 적용되는 것을 제외하고 $"..."작동 하는 인용 연산자 "..."가 있습니다 (사용자 언어로 번역되도록 구성 할 수 있음). in을 mksh무시합니다 .$$"..."

bash

같은 ksh93하지만 :

  • 1 바이트 문자 로케일에서 모든 공백 (로케일에 따라) 문자는 공백 또는 탭과 같은 분리 문자로 간주됩니다. 실제로, 일부 로케일에서 공백 문자 일 수있는 경우를 대비하여 8 번째 비트 세트로 모든 바이트를 인용해야합니다.
  • 대화식 인스턴스에서와 같이 csh 히스토리 확장이 사용 가능한 경우 !일부 컨텍스트에서 특별하며 큰 따옴표가 항상 이스케이프하지는 않습니다. 그리고 ^명령 시작 부분에서 특별합니다.

zsh

같은 ksh93하지만 :

  • bashcsh 히스토리 확장 과 동일한 참고 사항
  • =단어의 첫 문자로 =ls확장됩니다 (로 확장 /bin/ls).
  • {과 }(와 같이 구분하지 않는 경우도 열고 닫을 명령 그룹 수 {echo text}Bourne 씨의 같은 작품 { echo text;}).
  • [단독으로 제외하고으로 [닫지 않아도 인용이 필요합니다 ].
  • 으로 extendedglob옵션이 활성화 #, ^및 ~연산자를 globbing을한다.
  • braceccl옵션을 사용하면 {non-empty-string}특별합니다.
  • $"..." 지원되지 않습니다.
  • 특수한 특기 사항 으로, 단어의 시작 부분에서 ( 작업 스펙 을 허용하기 위해) (따옴표가 있거나 확장 된 경우)를 따를 ?때 특별하지 않습니다.%%?name
  • rcquotes(기본적으로 활성화되지 않음) 옵션은 하나가 아니라 작은 따옴표 입력 할 수 있습니다 ''라 à 내부에 작은 따옴표 rc(아래 참조).

yash

같은 POSIX것을 제외시켰다.

  • 모든 공백 문자는 구분 기호로 간주됩니다.
  • 이 brace-expand옵션을 사용하면 zsh 스타일 괄호 확장을 구현합니다.

모든 셸에는 따옴표가 다르게 작동하는 특수한 컨텍스트가 있습니다. 우리는 이미 여기에 문서와 백틱을 언급했지만 [[...]]ksh와 다른 쉘 인 POSIX $((...))에도 있습니다 case...

또한 인용에는 확장 (큰 따옴표 포함) 또는 문서 구분 기호에 적용될 때 다른 부작용이있을 수 있습니다. 또한 예약어를 비활성화하고 별칭 확장에 영향을줍니다.

요약

Bourne과 같은 쉘에서 !#$^&*?[(){}<>~;'"`\|=, SPC, TAB, NEWLINE 및 8 비트 세트가있는 일부 바이트는 (적어도 일부 컨텍스트에서는) 특수하거나 특수 할 수 있습니다.

문자 그대로 처리되도록 특별한 의미를 제거하려면 따옴표를 사용합니다.

사용하다:

  • '...' 모든 캐릭터의 특별한 의미를 제거하려면 :

    printf '%s\n' '\/\/ Those $quoted$ strings are passed literally as
    single arguments (without the enclosing quotes) to `printf`'
  • \ 한 문자의 특별한 의미 만 제거하려면 :

    printf '<%s>\n' foo bar\ baz #comment

    위의 a 앞에 오는 공백 문자 만 \문자 그대로로 전달됩니다 printf. 다른 것은 쉘에서 토큰 분리 문자로 처리됩니다.

  • 사용 "..."여전히 매개 변수 확장 허용하면서 문자를 인용 ( $var, $#, ${foo#bar}...), 산술 확장 ( $((1+1))또한 $[1+1]일부 포탄에) 및 명령 치환 ( $(...)또는 이전 형태 `...`. 사실, 대부분의 시간, 당신은 할 내부 이러한 확장을 데려 가고 싶다는 어쨌든 큰 따옴표를 사용 하여 여전히 특수한 문자 (단지 문자)의 특수 의미를 제거하기 위해 \within "..."을 사용할 수 있습니다 .
  • 문자열에 '문자 가 포함되어 있으면 '...'나머지에 계속 사용할 수 '있고 "'"또는 인용 \'가능 하거나 인용 가능한 다른 인용 메커니즘을 사용할 수 있습니다 $'\''.

    echo 'This is "tricky", isn'\''t it?'
  • 현대적인 $(...)형태의 명령 대체를 사용하십시오 . `...`Bourne 쉘과의 호환성, 예를 들어 매우 오래된 시스템과의 호환성을 위해 이전 버전 만 사용하고 다음 과 같이 사용하지 않는 변수 할당에서만 사용하십시오.

    echo "`echo "foo bar"`"

    Bourne 쉘 또는 AT & T 버전의 ksh에서는 작동하지 않습니다. 또는:

    echo "`echo \"foo bar\"`"

    Bourne 및 AT & T ksh와 함께 작동하지만와 함께 작동하지 yash않지만 다음을 사용합니다.

    var=`echo "foo bar"`; echo "$var"

    그것은 모두와 함께 작동합니다.

    큰 따옴표로 이식 가능하게 중첩하는 것도 불가능하므로 변수를 사용하십시오. 또한 특수 백 슬래시 처리에주의하십시오.

    var=`printf '%s\n' '\\'`

    백틱 내에 $var백 슬래시 처리 (for \,`및 $(및을 "제외하고 인용 된 경우 yash)) 수준이 있으므로 내부에 하나의 백 슬래시 만 저장 합니다.

    var=`printf '%s\n' '\\\\'`

    또는

    var=`printf '%s\n' '\\\'

    대신에.

Csh 가족

csh와 tcsh는 구문이 상당히 다르지만 Bourne 쉘과 공통된 유산이 있기 때문에 여전히 공통점이 많습니다.

특수 문자:

  • "\'&|;()^`<>$, 공백, 줄 바꿈 및 탭은 인용되지 않은 모든 곳에서 특별합니다.
  • #(csh는 #주석 리더로 소개 된 셸입니다 ) 스크립트 시작시 또는 인용되지 않은 공백, 탭 또는 줄 바꿈을 따르는 것이 특별합니다.
  • *?[ 목록 컨텍스트에서 globbing 연산자만큼 특별합니다.
  • {non-empty-string} 특별하다 (csh는 괄호 확장을 도입 한 쉘이다).
  • !및 ^이력 확장 (다시, CSH 발명)의 일부로서 특정하고, 인용 규칙은 특별하다.
  • ~ (물결 확장 또한 csh 발명) 일부 상황에서는 특별합니다.

인용 연산자

Bourne 쉘과 동일하지만 동작이 다릅니다. tcsh는 구문 관점에서 csh처럼 동작합니다. 많은 csh 버전에 버그가있는 것을 알 수 있습니다. ctc의 대략적인 버전을 얻으려면 최신 버전의 tcsh를 얻으십시오.

  • \개행을 제외한 단일 문자를 이스케이프합니다 (Bourne 쉘과 동일). 이스케이프 할 수있는 유일한 인용 연산자입니다 !. \<newline>이스케이프하지 않고 명령 구분 기호에서 공백으로 토큰 구분 기호로 변환합니다.
  • "..."자체 제외한 모든 문자를 탈출 $, `, 줄 바꿈 및 !. Bourne 쉘과 달리 \이스케이프 $및 `내부 "..."를 사용할 수는 없지만 \이스케이프 !또는 개행을 사용할 수는 있습니다 (단 !, 개행 이전의 경우를 제외하고 는 사용할 수 없음 ). 리터럴 !은 "\!"이고 리터럴 \!은 "\\!"입니다.
  • '...' 자체를 제외한 모든 문자 !와 줄 바꿈을 이스케이프합니다 . 큰 따옴표와 마찬가지로 !백 슬래시로 줄 바꿈을 이스케이프 처리 할 수 ​​있습니다.
  • 명령 대체는 `...`구문을 통해서만 이루어 지며 안정적으로 사용될 수 없습니다.
  • 변수 대체는 상당히 잘못 설계되어 오류가 발생하기 쉽습니다. $var:q운영자는보다 안정적인 코드를 포함하는 변수를 작성하는 데 도움이됩니다.

요약

가능하면 csh에서 멀리 떨어지십시오. 사용할 수없는 경우 :

  • 작은 따옴표는 대부분의 문자를 인용합니다. !그리고 줄 바꿈에는 여전히 \.
  • \ 대부분의 캐릭터를 탈출 할 수 있습니다
  • "..."그 안에 일부 확장을 허용 할 수 있지만 개행 문자 및 / 또는 백 슬래시 문자를 포함하면 작은 버그가 있습니다. 작은 따옴표 만 사용하고 $var:q변수 확장에 가장 좋습니다 . 배열의 요소를 안정적으로 결합하려면 루프를 사용해야합니다.

rc 가족

rc는 IS plan9쉘와 그 하위 같은 es및 akanga유닉스와 유닉스 좋아하는에 이식되고있다. 그것은 훨씬 더 깨끗하고 더 나은 구문을 가진 쉘이며, 이전 버전과의 호환성을 위해 Bourne과 같은 쉘을 고수하지 않은 경우 모두가 사용할 것입니다.

rc/akanga

특수 문자

  • #;&|^$=`'{}()<>, SPC, TAB 및 NEWLINE은 인용되지 않은 경우 항상 특별합니다.
  • *?[ 장갑을 끼고 있습니다.

인용 연산자

'...'유일한 인용 연산자입니다. 리터럴 '은 다음과 ''같이 작은 따옴표 안에 작성 됩니다.

 echo 'it''s so simple isn''t it?'

es

es에 기반한 실험용 쉘로 볼 수 있습니다 rc.

그래도 약간의 차이가 있습니다. 이 Q / A에 관심이있는 것 중 하나는 \인용 연산자 (개행을 제외한 모든 특수 문자를 인용)이며 \n개행, \b백 슬래시 와 같은 이스케이프 시퀀스를 도입하는 데에도 사용할 수 있다는 것입니다 .

물고기

fish는 상대적으로 새로 온 사람이며 (2005 년경) 주로 대화식으로 사용되며 다른 셸과는 상당히 다른 구문을 사용합니다.

특수 문자

  • "'\()$%{}^<>;&|인용되지 않은 경우 항상 특별합니다 %((pid 확장의 경우)는 다른 쉘과의 중요한 차이점으로, `특별하지는 않습니다)
  • # 따옴표없는 공간, 탭, 줄 바꿈 또는 ;&|^<>
  • *?(하지만 [...]) 글 로빙 사업자

인용 연산자

  • \개행을 제외한 단일 특수 문자를 인용하지만 C 이스케이프 시퀀스 ( \n, \b...) 도입 자로도 두 배가됩니다 . IOW \n는 인용 된 n것이 아니라 개행입니다.
  • "..."자체를 제외한 모든 것을 인용 $하며 백 슬래시와 백 슬래시는이를 피하기 위해 사용될 수 있습니다. \<newline>내부의 줄 연속 (제거) "..."입니다.
  • '...'자체와를 제외한 모든 것을 인용 \하면 백 슬래시를 사용하여 이스케이프 처리 할 수 ​​있습니다.

(즉, 그래서 나는 모든 상황에서 오직 사람의 특별한을 포함 시켰 c와 같은 역할을 \c, c출력을하지 않는 c: command not found등, STDERR에) 내가 말하는거야 sh여기. 또한 이것은 "정리"질문입니다. 즉, 그러한 모든 문자를 다루기 위해 여기에 있으므로 19 개 이상의 질문을 할 필요가 없습니다. 질문은 다른 캐릭터에 대해 다른 질문이 제기 된 사건으로 인해 게시되었습니다. 우리는 반드시 여기에서 정리하고 싶습니다!
— EKons

글쎄, ?[연산자를 움켜 쥐고 있지만 모든 상황에서 특별하지는 않지만 현재 디렉토리의 내용을 나쁘게 이스케이프 처리 *하기 때문에 (아무것도 탈출하지 않음) 것 같습니다. 리터럴을 에코하고 리터럴 을 에코합니다 . 또한, 글 로빙 오버 버터이기도합니다. echo *echoecho ??echo [[]
— EKons

1
@ ΈρικΚωνσταντόπουλος *는 glob가 숨겨지지 않은 모든 파일, 숨겨지지 ?않은 단일 문자 파일, [a-z]이름이 a와 z 사이의 단일 문자 인 파일로 확장됩니다. ?쉘에 따라 파일과 일치하지 않는 경우 (예 :와 같이) 일치하지 않는 오류가 발생하거나 패턴이 자체로 확장됩니다. 어쨌든 자신이 확장되는 쉘에서도 파일과 일치 할 경우 인용해야 합니다.
— Stéphane Chazelas

그러나, 글로브가 아닌, *여전히 무언가로 확장됩니다.
— EKons

@ ΈρικΚωνσταντόπουλος *는? 일치하지 않는 경우 ( *단독의 경우, 현재 디렉토리에 숨겨진 파일 만있는 경우, a*그 이름이 a...로 시작하는 파일이없는 경우 ) 자체 (대부분의 본쉘), 또는 불일치 오류 (제기 csh, tcsh, fish, (경고) zsh, bash -O failglob또 다른 패턴이있다 (또는 팽창 일부 쉘의 경우 또는 nullglob 옵션을 아무것도 초기 유닉스 쉘) 팽창에 그 csh, tcsh, zsh -o cshnullglob, 초기 유닉스 쉘의 무언가).
— Stéphane Chazelas

4

1. 탈출

다음과 \같이를 사용하여 이러한 모든 문자를 이스케이프 하십시오 (줄 바꾸기 / 캐리지 리턴에서는 작동하지 않음).

$ echo Use a \"\\\" symbol to escape characters.
Use a "\" symbol to escape characters.

2. 큰 따옴표

다음 "과 같이 전체 텍스트를 s 로 묶습니다 .

$ var=variables;echo "Enclose text in \"s. You can also use $var in them. `echo Surprise!!!`"
Enclose text in "s. You can also use variables in them. Surprise!!!

3. 작은 따옴표

큰 따옴표와 동일하지만 특별한 토큰이 없습니다.

$ proof=proveit;echo 'This should not read "proveit": $proof'
This should not read "proveit": $proof

1
fish작은 따옴표가 모든 문자를 인용하는 Bourne과 같은 쉘이 아닌 쉘 의 동작을 설명합니다 (백 슬래시는 내부에서 특별하지 않습니다 '...'). 에 있습니다 fish, %또한 특수 문자입니다.
— Stéphane Chazelas

어떻게 StéphaneChazelas @ 모르겠어요 fish작품,하지만 내 경험에, 그이다 sh, echo '\\'에코 \ 및 echo '\''에코 '.
— EKons

1
echo '\\'echoANSI C 이스케이프 시퀀스를 확장 하기 때문에 \ 출력 합니다 (일부 echo구현에는 필요 echo -e '\\'). printf '%s\n' '\\'\\를 출력합니다.
— Stéphane Chazelas

참고 sh특정 쉘을 식별하지 않는이있다와라는 다른 종종 호환 쉘이 많이되었습니다 sh.
— Stéphane Chazelas

@ StéphaneChazelas 아, 알겠습니다. 이제 변경하겠습니다. 그건 그렇고, \'작은 따옴표 문자 시퀀스 안에 특수 토큰이 있습니까?
— EKons
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.