bash : 특수 문자가 포함 된 명령 줄 인수를 전달하는 방법


31

필자는 program입력으로 정규 표현식이 필요한 Linux 프로그램 을 작성했습니다 .

bash쉘 에서 프로그램을 호출하고 해당 정규 표현식을 명령 행 인수로 프로그램에 전달하려고합니다 (다른 명령 행 인수도 있음). 일반적인 정규식은 다음과 같습니다.

[abc]\_[x|y]

불행하게도 문자 [, ]그리고 |특수 문자입니다 bash. 따라서 전화

program [abc]\_[x|y] anotheragument

작동하지 않습니다. 일종의 이스케이프 문자 또는 따옴표 등을 사용하여 표현식을 전달하는 방법이 있습니까?

( program "[abc]\_[x|y] anotheragument"두 인자를 하나로 해석하기 때문에 호출 도 작동하지 않습니다.)

답변:


27

당신은 할 수 있습니다

  1. 백 슬래시 ()로 각 단일 특수 기호를 이스케이프 \[abc\]_\[x\|y\]하거나
  2. 에서와 같이 전체 인수를 큰 따옴표로 묶습니다 "[abc]_[x|y]".

편집 : 마찬가지로 일부 지적, dobleqouting이 변수 확장이나 명령어 치환을 방지하지 않습니다. 따라서 정규 표현식에 bash가 해석 할 수있는 것이 포함되어 있으면 작은 따옴표를 대신 사용하십시오.


4
bash에서 큰 따옴표는 확장 변수 또는 매개 변수 , 형식의 명령 대체 또는 산술 확장 , 기록 확장 또는 백 슬래시 이스케이프를 무시 하지 않습니다 . 작은 따옴표를 대신 사용하십시오. bash 매뉴얼의 "Quoting"섹션을 참조하십시오. "$HOME""${USER:-root}""$(date)""`date`""$((1 + 2))""!!""\\"
Flimm

25

작은 따옴표를 사용하십시오. 작은 따옴표는 어떤 문자도 해석되지 않도록합니다.

$ printf %s 'spaces  are  not  interpreted away
neither are new lines
nor variable names $TESTING
nor square brackets [TESTING]
nor pipe characters or redirection symbols | > <
nor the semicolon ;
nor backslashes \a \b \c \\
the only thing that does not work is the single quote itself
'

작은 따옴표를 포함해야하는 경우 두 가지 솔루션이 있습니다.

$ printf '%s\n' '[ Don'"'"'t worry, be happy! ]'
[ Don't worry, be happy! ]
$ printf '%s\n' '[ Don'\''t worry, be happy! ]'
[ Don't worry, be happy! ]

맞습니다. +1
antichris

6

man bash

이스케이프 문자 , 작은 따옴표 및 큰 따옴표 등 세 가지 인용 메커니즘이 있습니다 .

따옴표가없는 백 슬래시 ( \ )는 이스케이프 문자 입니다. <newline>을 제외하고 다음 문자의 리터럴 값을 유지합니다. 경우 \ <개행> 쌍 나타나고 슬래시가 인용되지 자체 \ <개행> (즉, 그것의 입력 스트림으로부터 제거하고 효과적으로 무시) 라인으로 연속 처리된다.

작은 따옴표로 문자를 묶으면 따옴표 안에 각 문자의 리터럴 값이 유지됩니다. 백 슬래시가 앞에 있어도 작은 따옴표 사이에는 작은 따옴표가 없을 수 있습니다.

큰 따옴표로 문자를 묶으면 $ , ` , \ 및 히스토리 확장이 활성화 된 경우를 제외하고 따옴표 내 모든 문자의 리터럴 값을 유지합니다 ! . 문자 $` 는 큰 따옴표 안에 특별한 의미를 유지합니다. 백 슬래시는 $ , ` , " , \ 또는 <newline> 문자 중 하나가 뒤에 오는 경우에만 특별한 의미를 유지합니다 . 큰 따옴표는 큰 따옴표 안에 백 슬래시를 붙여서 인용 할 수 있습니다. 그렇지 않으면 수행됩니다! 큰 따옴표로 표시되는 것은 백 슬래시를 사용하여 이스케이프됩니다. ! 앞에 오는 백 슬래시 제거되지 않습니다.

큰 따옴표로 묶인 경우 특수 매개 변수 *@ 는 특별한 의미를 갖습니다 (아래의 매개 변수 참조).

$ ' string ' 형식의 단어는 특별히 취급됩니다. ANSI C 표준에 지정된대로 백 슬래시 이스케이프 문자를 바꾸어 단어를 string으로 확장합니다 . 백 슬래시 이스케이프 시퀀스가있는 경우 다음과 같이 디코딩됩니다.

       \      경고 (벨)
        \ B      백 스페이스
        \ 전자 
       \ E      이스케이프 문자
        F \      용지 공급
        \ n      새로운 라인
        \ r에      캐리지 리턴
        \ t      수평 탭
        \ V      수직 탭
        \\      백 슬래시
        \ '      작은 따옴표
        \ "      큰 따옴표
        \ NNN    을 값이 8 진 값 nnn 인 8 비트 문자
              (1 ~ 3 자리)
       \ x HH    16 진수 값이 HH 인 8 비트 문자
              (하나 또는 두 개의 16 진수)
       \ u HHHH 값 이 유니 코드 (ISO / IEC 10646) 문자
              16 진 값 HHHH (1-4 자리 16 진수)
        \ U HHHHHHHH
              값이 유니 코드 (ISO / IEC 10646) 문자
              16 진 값 HHHHHHHHH ( 1-8 개의 16 진수)
        \ c x     제어 x 문자

확장 된 결과는 달러 기호가없는 것처럼 작은 따옴표로 묶습니다.

큰 따옴표로 묶은 문자열 앞에 달러 기호 ( $ " 문자열 " )가 있으면 문자열이 현재 로케일에 따라 변환됩니다. 현재 로케일이 C 또는 POSIX 인 경우 달러 기호는 무시됩니다. 문자열이 번역 및 교체되면 교체는 큰 따옴표로 묶습니다.


2

\특수 문자 앞에 백 슬래시 ( )를 사용하여 다음과 같이 이스케이프 할 수 있습니다.

john @ awesome : ~ # 에코 \ &
&

2

정규식으로 유용하지는 않지만 일부 문자 시퀀스는 Bash 변수 이름으로 해석 될 수 있습니다. 이 문제가 발생하지 않도록하고 확장되지 않도록하려면 큰 따옴표 대신 작은 따옴표를 사용하십시오.

program '[abc]_[x|y]' anotherargument

각 인수를 따로 인용하면 (인용이 필요한 경우) 독립 인수로 해석됩니다. 경우에 따라 배열을 사용할 수도 있습니다.

param_array=('[abc]_[x|y]' anotherargument)    # create an array
param_array+=(yetanother)     # append another element to the array
program "${param_array[@]}"   # use the array elements as arguments to program

1
program "[abc]_[x|y]"
program "[abc]_[x|y]" anotherargument

0

탈출하면 잘 작동합니다.

  programm \[abc\]_\[x\|y\]

0

패턴은 어디에서 왔습니까? 고정되었거나 사용자가 제공합니까? 로컬 시스템에서 스크립트를 호출하는 사용자입니까 아니면 원격 사용자입니까?

따옴표를 사용하여 셸에서 데이터를 해석하지 못하도록 데이터를 줄 바꿈합니다. 두 가지 옵션이 있습니다.

  1. 여전히 일부 해석을 허용하는 큰 따옴표 ($ expand 및`backticks`)
  2. 말 그대로 모든 것을 통과하는 작은 따옴표

$정규 표현식 (줄 끝 / 버퍼)에 유효한 문자 이기 때문에 변수에 저장하지 않는 한 작은 따옴표를 사용하여 정규 표현식을 유지하려고합니다. 신뢰할 수없는 사람으로부터 임의의 데이터를 복용하는 경우 교체해야합니다 '함께 '"'"'하고 단일 따옴표로 포장.

또는 세 개의 문자 중 하나와 실제로는 일치 하는 [abc]_[x|y]것처럼 보입니다 . 대괄호 는 범위 내 및 범위 시작시와 부정 시작시 문자 만 일치합니다 . 따라서 의미하는 바가 괄호는 쉘에 특수한 문자입니다. 사각 괄호는 하지 그들은처럼 그냥 보이는, 쉘에 특별한. 이중 대괄호 는 특별합니다.xyxy|-^[abc]_(x|y)[[ ... ]]


이것은 (I 교체를 위해 특히 명령을 주셔서 감사합니다 여기에 가장 정답 중 하나입니다 '함께 '"'"'하지만, 아직 정확하지 않습니다). [쉘에 대한 특수 문자이며 경로 확장을 수행 할 때 와일드 카드에 사용됩니다 (쉘은 인용되지 않은 모든 것을 수행합니다).
jpalecek

변수 첨자 또는 globbing과 같은 일부 상황에서는 특별하지만 여전히 입력 foo=a[b]한 다음 echo $foo문자열에 인용이 필요하지 않은 것을 볼 수 있습니다 . 네 말이 맞아 너무 짧았 어
Phil P

당신이 운이 있다면, 거기에 파일 ab현재 디렉토리에 다음 foo이 포함됩니다 ab보다는 a[b]. 대괄호, 사람들을 인용하십시오.
clacke

(명확하게하기 위해 : 나는 인용문을 원했던 곳에서 원래의 대답이 분명한 것처럼 인용한다.) 이 주장은 나를 놀라게 했으므로 테스트했습니다. zsh 또는 bash에서는 사실이 아니지만 BSD / bin / sh에서는 사실입니다. 이것은 POSIX에 위배되며 비표준 동작이므로 처리하려면 인용해야합니다. zsh에서는 setopt glob_assign이 동작도 활성화 할 수 있으므로 인용이 가장 안전합니다.
Phil P
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.