문제

하자, 당신은 강타가 있습니다 alias 처럼:

alias rxvt='urxvt'

잘 작동합니다.

하지만:

alias rxvt='urxvt -fg '#111111' -bg '#111111''

작동하지 않으며 둘 다 :

alias rxvt='urxvt -fg \'#111111\' -bg \'#111111\''

그렇다면 따옴표를 피한 후에는 문자열 내부의 인용문을 열고 닫는 방법을 어떻게 일치하게합니까?

alias rxvt='urxvt -fg'\''#111111'\'' -bg '\''#111111'\''

비록 당신이 그렇게 연결할 수 있다면 동일한 문자열을 나타내는 것처럼 보이지 않습니다.

도움이 되었습니까?

해결책

가장 바깥 쪽 레이어에서 단일 따옴표를 실제로 사용하려면 두 종류의 인용문을 모두 붙일 수 있습니다. 예시:

 alias rxvt='urxvt -fg '"'"'#111111'"'"' -bg '"'"'#111111'"'"
 #                     ^^^^^       ^^^^^     ^^^^^       ^^^^
 #                     12345       12345     12345       1234

방법에 대한 설명 '"'"' 단지 해석됩니다 ':

  1. ' 단일 따옴표를 사용하는 첫 번째 인용문.
  2. " 두 번째 인용문을 사용하여 두 번째 인용문을 시작하십시오.
  3. ' 인용 된 캐릭터.
  4. " 두 번째 인용문을 사용하여 두 번째 인용문을 사용합니다.
  5. ' 단일 따옴표를 사용하여 세 번째 인용문을 시작하십시오.

(1)과 (2) 또는 (4)와 (5) 사이에 공백을 배치하지 않으면 쉘은 그 줄을 하나의 긴 단어로 해석합니다.

다른 팁

나는 항상 내장 된 각 단일 견적을 시퀀스로 바꿉니다. '\'' 문자열을 닫고 탈출 한 단일 견적을 추가하고 문자열을 다시 연다


나는 종종 Perl 스크립트에서 "인용문"기능을 채찍질하여 나를 위해 이것을 할 수 있습니다. 단계는 다음과 같습니다.

s/'/'\\''/g    # Handle each embedded quote
$_ = qq['$_']; # Surround result with single quotes.

이것은 거의 모든 경우를 처리합니다.

당신이 소개 할 때 인생은 더 재미 있습니다 eval 쉘 스크립트로. 당신은 본질적으로 모든 것을 다시 선택해야합니다!

예를 들어, 위의 진술을 포함하는 quotify라는 Perl 스크립트를 만듭니다.

#!/usr/bin/perl -pl
s/'/'\\''/g;
$_ = qq['$_'];

그런 다음 올바르게 인용 된 문자열을 생성하는 데 사용하십시오.

$ quotify
urxvt -fg '#111111' -bg '#111111'

결과:

'urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

그런 다음 별명 명령에 복사/붙여 넣을 수 있습니다.

alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

(명령을 평가에 삽입 해야하는 경우 인용문을 다시 실행하십시오.

 $ quotify
 alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

결과:

'alias rxvt='\''urxvt -fg '\''\'\'''\''#111111'\''\'\'''\'' -bg '\''\'\'''\''#111111'\''\'\'''\'''\'''

평가로 복사/붙여 넣을 수 있습니다.

eval 'alias rxvt='\''urxvt -fg '\''\'\'''\''#111111'\''\'\'''\'' -bg '\''\'\'''\''#111111'\''\'\'''\'''\'''

bash 이후 2.04 통사론 $'string' (그냥 대신 'string'; 경고 : 혼동하지 마십시오 $('string'))는 또 다른 인용 메커니즘입니다 ANSI C- 유사 탈출 시퀀스 단일 크기의 버전으로 확장하십시오.

Simple example:

  $> echo $'aa\'bb'
  aa'bb

  $> alias myvar=$'aa\'bb'
  $> alias myvar
  alias myvar='aa'\''bb'

귀하의 경우 :

$> alias rxvt=$'urxvt -fg \'#111111\' -bg \'#111111\''
$> alias rxvt
alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

일반적인 탈출 시퀀스는 예상대로 작동합니다.

\'     single quote
\"     double quote
\\     backslash
\n     new line
\t     horizontal tab
\r     carriage return

아래는 사본+붙여 넣은 관련 문서입니다 man bash (버전 4.4) :

$ 'string'형식의 단어는 특별히 취급됩니다. 이 단어는 문자열로 확장되며, 백 슬래시에 이스케이프 된 문자는 ANSI C 표준으로 지정된대로 대체되었습니다. 백 슬래시 탈출 시퀀스는 존재하는 경우 다음과 같이 해독됩니다.

    \a     alert (bell)
    \b     backspace
    \e
    \E     an escape character
    \f     form feed
    \n     new line
    \r     carriage return
    \t     horizontal tab
    \v     vertical tab
    \\     backslash
    \'     single quote
    \"     double quote
    \?     question mark
    \nnn   the eight-bit character whose value is the octal 
           value nnn (one to three digits)
    \xHH   the eight-bit character whose value is the hexadecimal
           value HH (one or two hex digits)
    \uHHHH the Unicode (ISO/IEC 10646) character whose value is 
           the hexadecimal value HHHH (one to four hex digits)
    \UHHHHHHHH the Unicode (ISO/IEC 10646) character whose value 
               is the hexadecimal value HHHHHHHH (one to eight 
               hex digits)
    \cx    a control-x character

확장 된 결과는 마치 달러 표시가없는 것처럼 단일 인용됩니다.


보다 따옴표와 탈출 : 문자열과 같은 ansi c 자세한 내용은 bash-hackers.org 위키에서. 또한 주목하십시오 "배쉬 변경" 파일 (파일개요는 여기를 참조하십시오)과 관련된 변경 및 버그 수정에 대해 많은 언급 $'string' 인용 메커니즘.

unix.stackexchange.com에 따르면 특별한 캐릭터를 일반적인 캐릭터로 사용하는 방법? Bash, Zsh, MKSH, KSH93 및 FreeBSD 및 BusyBox SH에서 (일부 변형과 함께) 작동해야합니다.

나는 그의 블로그 (Link Pls?)에 항목이 보이지 않지만 GNU 참조 매뉴얼:

단일 따옴표 ( '' ')로 문자를 둘러싸는 것은 인용문 내에서 각 문자의 문자 값을 보존합니다. 백 슬래시가 앞서도 단일 따옴표 사이에 단일 견적이 발생할 수 없습니다.

그래서 Bash는 이해하지 못합니다.

alias x='y \'z '

그러나 이중 인용문으로 둘러싸여 있으면이 작업을 수행 할 수 있습니다.

alias x="echo \'y "
> x
> 'y

사용을 확인할 수 있습니다 '\'' 단일 인용 문자열 내부의 단일 인용은 Bash에서 작동하며 스레드의 이전의 "접착"인수와 같은 방식으로 설명 할 수 있습니다. 인용 된 문자열이 있다고 가정합니다. 'A '\''B'\'' C' (여기의 모든 따옴표는 단일 따옴표입니다). Echo로 전달되면 다음을 인쇄합니다. A 'B' C. 각 '\'' 첫 번째 인용문은 현재 단일 인용 문자열을 닫습니다. \' 이전 문자열에 단일 견적을 접착합니다 (\' 인용 된 문자열을 시작하지 않고 단일 견적을 지정하는 방법)이며 마지막 인용문은 다른 단일 인용 문자열을 엽니 다.

쉘에서 인용문을 피하는 간단한 예 :

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

이미 열린 하나를 마무리하여 완료되었습니다 ('), 탈출 한 배치 (\'), 그런 다음 다른 하나를 열었습니다 ('). 이 구문은 모든 명령에 대해 작동합니다. 첫 번째 답변과 매우 유사한 접근 방식입니다.

탈출 한 단일 인용 문자 ( ')를 사용하여 연결을 사용하거나 단일 인용문 문자를 이중 인용문 ( "'") 내에 둘러싸여 동의하여 두 버전이 작동합니다.

이 질문의 저자는 그의 마지막 탈출 시도가 끝날 때 추가 단일 인용문 ( ')이 있다는 것을 알지 못했습니다.

alias rxvt='urxvt -fg'\''#111111'\'' -bg '\''#111111'\''
           │         │┊┊|       │┊┊│     │┊┊│       │┊┊│
           └─STRING──┘┊┊└─STRIN─┘┊┊└─STR─┘┊┊└─STRIN─┘┊┊│
                      ┊┊         ┊┊       ┊┊         ┊┊│
                      ┊┊         ┊┊       ┊┊         ┊┊│
                      └┴─────────┴┴───┰───┴┴─────────┴┘│
                          All escaped single quotes    │
                                                       │
                                                       ?

이전의 멋진 ASCII/유니 코드 아트에서 볼 수 있듯이 마지막 탈출 한 단일 인용문 ( ')은 불필요한 단일 인용문 (')이 뒤 따릅니다. Notepad ++에있는 것과 같은 구문 높이 라이터를 사용하면 매우 도움이 될 수 있습니다.

다음과 같은 다른 예제에 대해서도 마찬가지입니다.

alias rc='sed '"'"':a;N;$!ba;s/\n/, /g'"'"
alias rc='sed '\'':a;N;$!ba;s/\n/, /g'\'

이 두 가지 아름다운 별칭 사례는 파일의 정렬을 어떻게 정렬 할 수 있는지 매우 복잡하고 난독 화 된 방식으로 보여줍니다. 즉, 라인이 많은 파일에서 이전 줄의 내용 사이에 쉼표와 공간이있는 한 줄만 얻습니다. 이전 의견을 이해하기 위해 다음이 예입니다.

$ cat Little_Commas.TXT
201737194
201802699
201835214

$ rc Little_Commas.TXT
201737194, 201802699, 201835214

나는 대체 접근법을 고려하는 것이 합리적이기 때문에 인용문 문제를 구체적으로 다루고 있지 않습니다.

rxvt() { urxvt -fg "#${1:-000000}" -bg "#${2:-FFFFFF}"; }

그런 다음 다음으로 호출 할 수 있습니다.

rxvt 123456 654321

아이디어는 이제 인용문에 대한 걱정없이 이것을 별칭 할 수 있다는 것입니다.

alias rxvt='rxvt 123456 654321'

또는 포함 해야하는 경우 # 어떤 이유로 든 모든 전화에서 :

rxvt() { urxvt -fg "${1:-#000000}" -bg "${2:-#FFFFFF}"; }

그런 다음 다음으로 호출 할 수 있습니다.

rxvt '#123456' '#654321'

물론 별칭은 다음과 같습니다.

alias rxvt="rxvt '#123456' '#654321'"

(죄송합니다, 나는 내가 인용문을 다루었다고 생각합니다 :)

나는 단지 쉘 코드를 사용합니다 \x27 또는 \\x22 해당되는 경우. 번거 로움이 없습니다.

단일 인용 문자열 내에 단일 따옴표를 넣을 수 없으므로 가장 간단하고 가장 읽기 쉬운 옵션은 Heredoc 문자열을 사용하는 것입니다.

command=$(cat <<'COMMAND'
urxvt -fg '#111111' -bg '#111111'
COMMAND
)

alias rxvt=$command

위의 코드에서 Heredoc은 cat 명령 및 그 출력은 명령 대체 표기법을 통해 변수에 할당됩니다. $(..)

Heredoc 주위에 단일 인용문을하는 것이 필요합니다. $()

IMHO 진정한 대답은 단일 인용 문자열 내에서 단일 크기를 피할 수 없다는 것입니다.

그것은 불가능.

우리가 Bash를 사용한다고 가정하면.

Bash Manual에서 ...

Enclosing characters in single quotes preserves the literal value of each
character within the quotes.  A single quote may not occur
between single quotes, even when preceded by a backslash.

다른 문자열 탈출 메커니즘 중 하나를 사용해야합니다 "또는

마법은 없습니다 alias 그것은 단일 따옴표를 사용해야합니다.

Bash에서 다음과 같은 작업.

alias rxvt="urxvt -fg '#111111' -bg '#111111'"
alias rxvt=urxvt\ -fg\ \'#111111\'\ -bg\ \'#111111\'

후자는 를 사용하여 공간 문자를 피합니다.

단일 따옴표가 필요한 #111111에 대한 마법도 없습니다.

다음 옵션은 RXVT 별칭이 예상대로 작동한다는 점에서 다른 두 가지 옵션과 동일한 결과를 달성합니다.

alias rxvt='urxvt -fg "#111111" -bg "#111111"'
alias rxvt="urxvt -fg \"#111111\" -bg \"#111111\""

귀찮은 #을 직접 탈출 할 수도 있습니다

alias rxvt="urxvt -fg \#111111 -bg \#111111"

이 답변의 대부분은 당신이 묻는 특정 사례에 부딪칩니다. 친구와 내가 개발 한 일반적인 접근 방식이 있습니다. 여러 층의 쉘 확장을 통해 BASH 명령을 인용 해야하는 경우, SSH, SSH, su -c, bash -c, 기본 배쉬에는 필요한 하나의 핵심 프리미티브가 있습니다.

quote_args() {
    local sq="'"
    local dq='"'
    local space=""
    local arg
    for arg; do
        echo -n "$space'${arg//$sq/$sq$dq$sq$dq$sq}'"
        space=" "
    done
}

이것은 정확히 그 말을합니다. 그것은 각 인수를 개별적으로 인용합니다 (물론 배쉬 확장 후) :

$ quote_args foo bar
'foo' 'bar'
$ quote_args arg1 'arg2 arg2a' arg3
'arg1' 'arg2 arg2a' 'arg3'
$ quote_args dq'"'
'dq"'
$ quote_args dq'"' sq"'"
'dq"' 'sq'"'"''
$ quote_args "*"
'*'
$ quote_args /b*
'/bin' '/boot'

그것은 하나의 확장 층에 대해 명백한 일을합니다.

$ bash -c "$(quote_args echo a'"'b"'"c arg2)"
a"b'c arg2

(이중 인용문은 주변에 주목하십시오 $(quote_args ...) 결과를 단일 인수로 만드는 데 필요합니다. bash -c.) 그리고 여러 층의 확장 층을 통해 올바르게 인용하는 데보다 일반적으로 사용될 수 있습니다.

$ bash -c "$(quote_args bash -c "$(quote_args echo a'"'b"'"c arg2)")"
a"b'c arg2

위의 예 :

  1. 쉘-각 인수를 내부로 인출합니다 quote_args 그 결과 결과 출력을 단일 인수로 결합하여 내부 이중 인용문을 결합합니다.
  2. 껍질 인출 bash, -c, 1 단계에서 이미 인용 한 결과, 결과를 외부 이중 인용문과 단일 인수로 결합합니다.
  3. 그 엉망진창을 외부로 보냅니다 bash -c.

그것이 간단히 말해서 아이디어입니다. 이것으로 꽤 복잡한 일을 할 수 있지만 평가 순서와 어떤 하위 문자가 인용되는지주의해야합니다. 예를 들어, 다음은 잘못된 일을합니다 ( "잘못된"의 일부 정의를 위해) :

$ (cd /tmp; bash -c "$(quote_args cd /; pwd 1>&2)")
/tmp
$ (cd /tmp; bash -c "$(quote_args cd /; [ -e *sbin ] && echo success 1>&2 || echo failure 1>&2)")
failure

첫 번째 예에서는 Bash가 즉시 확장됩니다 quote_args cd /; pwd 1>&2 두 개의 별도 명령으로 quote_args cd / 그리고 pwd 1>&2, 그래서 CWD는 여전히 있습니다 /tmppwd 명령이 실행됩니다. 두 번째 예제는 글로브와 유사한 문제를 보여줍니다. 실제로, 동일한 기본 문제는 모든 bash 확장으로 발생합니다. 여기서 문제는 명령 대체가 함수 호출이 아니라는 것입니다. 문자 그대로 하나의 bash 스크립트를 평가하고 다른 Bash 스크립트의 일부로 출력을 사용하고 있습니다.

단순히 쉘 연산자를 탈출하려고하면 결과 문자열이 전달되어 실패합니다. bash -c 연산자로 해석되지 않는 개별적으로 인용 된 문자열의 시퀀스 일뿐입니다.

$ (cd /tmp; echo "$(quote_args cd /\; pwd 1\>\&2)")
'cd' '/;' 'pwd' '1>&2'
$ (cd /tmp; echo "$(quote_args cd /\; \[ -e \*sbin \] \&\& echo success 1\>\&2 \|\| echo failure 1\>\&2)")
'cd' '/;' '[' '-e' '*sbin' ']' '&&' 'echo' 'success' '1>&2' '||' 'echo' 'failure' '1>&2'

여기서 문제는 당신이 과도하게 인용한다는 것입니다. 당신이 필요로하는 것은 운영자가 동봉에 대한 입력으로 인용되지 않는 것입니다. bash -c, 그들은 외부에 있어야한다는 것을 의미합니다 $(quote_args ...) 명령 대체.

결과적으로, 가장 일반적인 의미에서해야 할 일은 명령 대체 시점에 명령 대체 시점에 확장되지 않도록 의도되지 않은 각 단어의 단어를 껍질을 벗기는 것입니다.

$ (cd /tmp; echo "$(quote_args cd /); $(quote_args pwd) 1>&2")
'cd' '/'; 'pwd' 1>&2
$ (cd /tmp; bash -c "$(quote_args cd /); $(quote_args pwd) 1>&2")
/
$ (cd /tmp; echo "$(quote_args cd /); [ -e *$(quote_args sbin) ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")
'cd' '/'; [ -e *'sbin' ] && 'echo' 'success' 1>&2 || 'echo' 'failure' 1>&2
$ (cd /tmp; bash -c "$(quote_args cd /); [ -e *$(quote_args sbin) ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")
success

이 작업을 마치면 전체 문자열은 임의의 평가 수준에 대한 추가 인용을위한 공정한 게임입니다.

$ bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); $(quote_args pwd) 1>&2")"
/
$ bash -c "$(quote_args bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); $(quote_args pwd) 1>&2")")"
/
$ bash -c "$(quote_args bash -c "$(quote_args bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); $(quote_args pwd) 1>&2")")")"
/
$ bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); [ -e *$(quote_args sbin) ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")"
success
$ bash -c "$(quote_args bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); [ -e *sbin ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")")"
success
$ bash -c "$(quote_args bash -c "$(quote_args bash -c "$(quote_args cd /tmp); $(quote_args bash -c "$(quote_args cd /); [ -e *$(quote_args sbin) ] && $(quote_args echo success) 1>&2 || $(quote_args echo failure) 1>&2")")")"
success

등.

이 예제는 같은 단어를 감안할 때 과도하게 보일 수 있습니다 success, sbin, 그리고 pwd 쉘 크기가 필요할 필요는 없지만 임의의 입력을 취하는 스크립트를 작성할 때 기억해야 할 핵심 사항은 확실하지 않은 모든 것을 인용하고 싶다는 것입니다. 그렇지 않습니다 사용자가 언제 던질 지 알지 못하기 때문에 인용이 필요합니다. Robert'; rm -rf /.

표지 아래에서 무슨 일이 일어나고 있는지 더 잘 이해하려면 두 개의 작은 헬퍼 기능으로 놀 수 있습니다.

debug_args() {
    for (( I=1; $I <= $#; I++ )); do
        echo -n "$I:<${!I}> " 1>&2
    done
    echo 1>&2
}

debug_args_and_run() {
    debug_args "$@"
    "$@"
}

이는 각 인수를 실행하기 전에 명령에 열거합니다.

$ debug_args_and_run echo a'"'b"'"c arg2
1:<echo> 2:<a"b'c> 3:<arg2> 
a"b'c arg2

$ bash -c "$(quote_args debug_args_and_run echo a'"'b"'"c arg2)"
1:<echo> 2:<a"b'c> 3:<arg2> 
a"b'c arg2

$ bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run echo a'"'b"'"c arg2)")"
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'echo' 'a"b'"'"'c' 'arg2'> 
1:<echo> 2:<a"b'c> 3:<arg2> 
a"b'c arg2

$ bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run echo a'"'b"'"c arg2)")")"
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'bash' '-c' ''"'"'debug_args_and_run'"'"' '"'"'echo'"'"' '"'"'a"b'"'"'"'"'"'"'"'"'c'"'"' '"'"'arg2'"'"''> 
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'echo' 'a"b'"'"'c' 'arg2'> 
1:<echo> 2:<a"b'c> 3:<arg2> 
a"b'c arg2

$ bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run bash -c "$(quote_args debug_args_and_run echo a'"'b"'"c arg2)")")")"
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'bash' '-c' ''"'"'debug_args_and_run'"'"' '"'"'bash'"'"' '"'"'-c'"'"' '"'"''"'"'"'"'"'"'"'"'debug_args_and_run'"'"'"'"'"'"'"'"' '"'"'"'"'"'"'"'"'echo'"'"'"'"'"'"'"'"' '"'"'"'"'"'"'"'"'a"b'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'c'"'"'"'"'"'"'"'"' '"'"'"'"'"'"'"'"'arg2'"'"'"'"'"'"'"'"''"'"''> 
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'bash' '-c' ''"'"'debug_args_and_run'"'"' '"'"'echo'"'"' '"'"'a"b'"'"'"'"'"'"'"'"'c'"'"' '"'"'arg2'"'"''> 
1:<bash> 2:<-c> 3:<'debug_args_and_run' 'echo' 'a"b'"'"'c' 'arg2'> 
1:<echo> 2:<a"b'c> 3:<arg2> 
a"b'c arg2

주어진 예에서는 단순히 단순한 인용문 대신 외부 탈출 메커니즘으로 이중 인용문을 사용했습니다.

alias rxvt="urxvt -fg '#111111' -bg '#111111'"

이 접근법은 고정 문자열을 명령에 전달하려는 많은 경우에 적합합니다. echo, 필요한 경우 등 슬래시로 캐릭터를 탈출하십시오.

예에서는 이중 인용문이 문자열을 보호하기에 충분하다는 것을 알 수 있습니다.

$ echo "urxvt -fg '#111111' -bg '#111111'"
urxvt -fg '#111111' -bg '#111111'

위에서 언급 한 진정한 답변에 대한 정교함은 다음과 같습니다.

때때로 나는 ssh를 통해 rsync를 사용하여 다운로드 할 것이며 '그것에 두 번'라는 파일 이름을 피해야합니다! (OMG!) 한 번 Bash와 SSH의 경우 한 번. 교대 인용 구분 자원의 동일한 원리가 여기에서 작동합니다.

예를 들어, 우리가 얻고 싶다고 가정 해 봅시다 : Louis Theroux의 LA 이야기 ...

  1. 먼저 Bash에 대한 단일 따옴표로 Louis Theroux를 동봉하고 SSH의 이중 인용문 : ' "Louis Theroux"'
  2. 그런 다음 단일 따옴표를 사용하여 이중 인용문을 피하십시오 ' "'
  3. Apostrophe를 피하기 위해 이중 인용문을 사용합니다 " '"
  4. 그런 다음 #2를 반복하고 단일 따옴표를 사용하여 이중 인용문을 피하십시오 ' "'
  5. 그런 다음 Bash에 대한 단일 따옴표로 LA 이야기를 동봉하고 SSH에 대한 이중 인용문 : ' "LA Stories"'

그리고 보라! 당신은 이것으로 감습니다 :

rsync -ave ssh '"Louis Theroux"''"'"'"'"''"s LA Stories"'

작은 일이 끔찍한 일입니다. 그러나 거기에서 당신은 간다

너무 많은 중첩 인용 계층의 문제를 해결하는 또 다른 방법 :

당신은 너무 작은 공간에 너무 많이 들어 가려고하므로 배쉬 기능을 사용하십시오.

문제는 너무 많은 수준의 중첩을 사용하려고 노력하고 있으며 기본 별명 기술은 수용하기에 충분히 강력하지 않습니다. 이와 같은 bash 기능을 사용하여 단일, 이중 인용문 진드기를 만들고 매개 변수로 전달되는 모든 것이 예상대로 정상적으로 처리됩니다.

lets_do_some_stuff() {
    tmp=$1                       #keep a passed in parameter.
    run_your_program $@          #use all your passed parameters.
    echo -e '\n-------------'    #use your single quotes.
    echo `date`                  #use your back ticks.
    echo -e "\n-------------"    #use your double quotes.
}
alias foobarbaz=lets_do_some_stuff

그런 다음 $ 1 및 $ 2 변수와 단일, 이중 따옴표 및 등진을 사용할 수 있습니다.

이 프로그램 인쇄 :

el@defiant ~/code $ foobarbaz alien Dyson ring detected @grid 10385
alien Dyson ring detected @grid 10385
-------------
Mon Oct 26 20:30:14 EDT 2015
-------------
shell_escape () {
    printf '%s' "'${1//\'/\'\\\'\'}'"
}

구현 설명 :

  • 이중 인용구는 단일 따옴표를 쉽게 출력하고 사용할 수 있습니다. ${...} 통사론

  • Bash의 검색 및 교체는 다음과 같습니다. ${varname//search/replacement}

  • 우리는 교체하고 있습니다 ' ~와 함께 '\''

  • '\'' 단일을 인코딩합니다 ' 그렇게 :

    1. ' 단일 인용문을 종료합니다

    2. \' 인코딩 a ' (우리가 인용문 안에 있지 않기 때문에 백 슬래시가 필요합니다)

    3. ' 다시 한 번 인용합니다

    4. 배쉬는 사이에 공백이없는 줄을 자동으로 연결합니다

  • 거기에 \ 모든 전에 \ 그리고 ' 그것은 탈출 규칙이기 때문입니다 ${...//.../...} .

string="That's "'#@$*&^`(@#'
echo "original: $string"
echo "encoded:  $(shell_escape "$string")"
echo "expanded: $(bash -c "echo $(shell_escape "$string")")"

추신 : 이중 인용 문자열보다 훨씬 간단하기 때문에 항상 단일 인용 된 문자열로 인코딩합니다.

GNU 병렬 설치가있는 경우 내부 인용문을 사용할 수 있습니다.

$ parallel --shellquote
L's 12" record
<Ctrl-D>
'L'"'"'s 12" record'
$ echo 'L'"'"'s 12" record'
L's 12" record

버전 20190222에서도 할 수 있습니다 --shellquote 여러 번:

$ parallel --shellquote --shellquote --shellquote
L's 12" record
<Ctrl-D>
'"'"'"'"'"'"'L'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'s 12" record'"'"'"'"'"'"'
$ eval eval echo '"'"'"'"'"'"'L'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'s 12" record'"'"'"'"'"'"'
L's 12" record

모든 지원되는 쉘에서 문자열을 인용합니다 (뿐만 아니라 bash).

이 기능 :

quote () 
{ 
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}

인용을 허용합니다 ' 내부에 '. 이것으로 사용하십시오 :

$ quote "urxvt -fg '#111111' -bg '#111111'"
'urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

인용 한 줄이 단일 따옴표와 혼합 된 이중 인용문과 같이 더 복잡해지면 문자열을 변수 내부에서 인용하는 것이 매우 까다로울 수 있습니다. 그러한 경우가 나타나면 스크립트 내부에 인용 해야하는 정확한 선을 작성하십시오 (이와 유사).

#!/bin/bash

quote ()
{
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}

while read line; do
    quote "$line"
done <<-\_lines_to_quote_
urxvt -fg '#111111' -bg '#111111'
Louis Theroux's LA Stories
'single quote phrase' "double quote phrase"
_lines_to_quote_

출력 :

'urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''
'Louis Theroux'\''s LA Stories'
''\''single quote phrase'\'' "double quote phrase"'

단일 따옴표 안에 올바르게 인용 된 문자열.

분명히, 단순히 이중 인용문으로 둘러싸는 것이 더 쉬울 것이지만, 그 문제는 어디에 있습니까? 다음은 단일 따옴표 만 사용하는 답입니다. 대신 변수를 사용하고 있습니다 alias 증거를 위해 인쇄하기가 더 쉽지만 사용과 동일합니다. alias.

$ rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'
$ echo $rxvt
urxvt -fg '#111111' -bg '#111111'

설명

핵심은 단일 견적을 닫고 원하는만큼 다시 열 수 있다는 것입니다. 예를 들어 foo='a''b' 와 같다 foo='ab'. 그래서 당신은 단일 견적을 닫고 문자 그대로의 단일 견적을 던질 수 있습니다. \', 그런 다음 다음 단일 견적을 다시 열었습니다.

고장 다이어그램

이 다이어그램을 사용하면 괄호를 사용하여 단일 따옴표가 열리고 닫히는 위치를 보여줍니다. 인용문은 괄호처럼 "중첩"이 아닙니다. 또한 올바르게 적용되는 색상 하이라이트에주의를 기울일 수 있습니다. 인용 된 줄은 적갈색이며 \' 검은 색입니다.

'urxvt -fg '\''#111111'\'' -bg '\''#111111'\'    # original
[^^^^^^^^^^] ^[^^^^^^^] ^[^^^^^] ^[^^^^^^^] ^    # show open/close quotes
 urxvt -fg   ' #111111  '  -bg   ' #111111  '    # literal characters remaining

(이것은 본질적으로 Adrian 's와 동일한 대답이지만, 나는 이것이 더 잘 설명된다고 생각합니다. 또한 그의 대답은 끝에 2 개의 불필요한 단일 따옴표가 있습니다.)

다음은 또 다른 해결책입니다. 이 기능은 단일 논증을 취하고 위의 투표 대답이 설명하는 것처럼 단일 쿼트 문자를 사용하여 적절하게 인용합니다.

single_quote() {
  local quoted="'"
  local i=0
  while [ $i -lt ${#1} ]; do
    local ch="${1:i:1}"
    if [[ "$ch" != "'" ]]; then
      quoted="$quoted$ch"
    else
      local single_quotes="'"
      local j=1
      while [ $j -lt ${#1} ] && [[ "${1:i+j:1}" == "'" ]]; do
        single_quotes="$single_quotes'"
        ((j++))
      done
      quoted="$quoted'\"$single_quotes\"'"
      ((i+=j-1))
    fi
    ((i++))
  done
  echo "$quoted'"
}

따라서 다음과 같은 방식으로 사용할 수 있습니다.

single_quote "1 2 '3'"
'1 2 '"'"'3'"'"''

x="this text is quoted: 'hello'"
eval "echo $(single_quote "$x")"
this text is quoted: 'hello'

Python 2 또는 Python 3 내에서 쉘 스트링을 생성하는 경우 다음이 인수를 인용하는 데 도움이 될 수 있습니다.

#!/usr/bin/env python

from __future__ import print_function

try:  # py3
    from shlex import quote as shlex_quote
except ImportError:  # py2
    from pipes import quote as shlex_quote

s = """foo ain't "bad" so there!"""

print(s)
print(" ".join([shlex_quote(t) for t in s.split()]))

이것은 출력됩니다 :

foo ain't "bad" so there!
foo 'ain'"'"'t' '"bad"' so 'there!'
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top