%EC%97%90%EC%84%9C%20bash%20%ED%98%B8%EC%B6%9C%20%EB%B0%8F%20%22%EC%A2%85%EB%A3%8C%EB%90%98%EC%A7%80%20%EC%95%8A%EC%9D%80%20%EC%9D%B8%EC%9A%A9%20%EB%AC%B8%EC%9E%90%EC%97%B4%22%2F%22%EC%98%88%EA%B8%B0%EC%B9%98%20%EC%95%8A%EC%9D%80%20EOF%22.png)
이것을 문서화해야겠다고 생각했습니다. 저는 매우 간단한 것을 시도하고 있습니다. 에 env 변수를 설정하고 bash
인쇄합니다.
$ bash -c "a=1; echo a$a;"
a
$ bash -c "a=1; echo a\$a;"
a1
이제 나는 이와 똑같은 것을 원하지만 sh
(내 시스템에서는 )의 인수로 호출 ls -la $(which sh)
됩니다 /bin/sh -> dash
.
$ sh -c "bash -c "a=1; echo a\$a;""
a$a
# obviously I have to escape inner quotes:
$ sh -c "bash -c \"a=1; echo a\$a;\""
a
# escape the dollar once more?
$ sh -c "bash -c \"a=1; echo a\\$a\" "
sh: Syntax error: Unterminated quoted string
# nope... inner single quotes, then?
$ sh -c "bash -c 'a=1; echo a$a;'"
a
# nope... escape the single quotes?
$ sh -c "bash -c \'a=1; echo a$a;\'"
bash: -c: line 0: unexpected EOF while looking for matching `''
bash: -c: line 1: syntax error: unexpected end of file
a
sh: ': not found
# nope... escape the dollar too?
$ sh -c "bash -c \'a=1; echo a\$a;\'"
bash: -c: line 0: unexpected EOF while looking for matching `''
bash: -c: line 1: syntax error: unexpected end of file
a
sh: ': not found
그래서 내 질문은 - 이스케이프를 위한 적절한 구문은 무엇입니까? 그러면 sh -c [bash -c ...]
그냥 과 동일한 결과를 얻을 수 있습니까 bash -c ...
?
답변1
작은따옴표 안에는 특별한 의미를 갖는 문자가 없습니다. 큰따옴표 안에는 "\$`
특별한 의미가 있습니다. 외부에서 내부로 작업하세요. 먼저 외부 셸에서 어떤 문자열이 만들어졌는지 파악한 다음 내부 셸에서 이를 어떻게 만들지 알아보세요.
예를 들어, 변수가 a
외부 쉘에 정의되어 있지 않다고 가정하면
sh -c "bash -c \"a=1; echo a\$a;\""
외부 쉘은 로 확장되는 큰따옴표로 묶인 문자열을 보고 bash -c "a=1; echo a$a;"
, 중간 셸에 전달되는 문자열입니다 sh
. 이를 두 개의 인수 및 를 사용한 sh
호출로 구문 분석합니다 . 후자는 변수가 정의되지 않은 큰따옴표로 묶인 문자열을 확장한 결과입니다.bash
-c
a=1; echo a;
"a=1; echo a$a;"
a
"a=1; echo a\$a;"
이 분석을 수행하면 원하는 것을 얻는 한 가지 방법이 이 단계에서 얻는 것임을 알 수 있습니다 . 이 추가 백슬래시를 얻으려면 원본에 두 개의 백슬래시를 넣어야 합니다. 이미 큰따옴표 안에 셸 확장의 한 단계가 있었기 때문입니다. 2 더하기 1은 3입니다.
sh -c "bash -c \"a=1; echo a\\\$a;\""
바깥쪽 문자열에 작은따옴표를 사용하는 것이 더 간단할 것입니다. 왜냐하면 거기에 있는 어떤 것도 확장하고 싶지 않기 때문입니다.
sh -c 'bash -c "a=1; echo a\$a;"'
bash
어느 쪽에서든 호출할 때 아무 것도 확장하고 싶지 않으므로 sh
거기에서도 작은따옴표를 사용할 수 있습니다. 작은따옴표로 묶인 문자열 안에 작은따옴표를 넣을 수는 없지만 이를 시뮬레이션하는 방법이 있습니다: put '\''
. 공식적으로 이는 작은 따옴표 리터럴을 종료하고 리터럴 작은 따옴표를 추가하고 새 작은 따옴표 리터럴을 시작하지만 4문자 시퀀스 '\''
는 작은 따옴표 문자열 안에 작은 따옴표를 넣는 방법으로 생각할 수 있습니다 .
sh -c 'bash -c '\''a=1; echo a$a;'\'''
마지막에 생략해도 됩니다 ''
. 덜 체계적이지만 눈에는 더 편합니다.
sh -c 'bash -c '\''a=1; echo a$a;'\'
작은따옴표는 큰따옴표 안에 있는 특별한 것이 아니므로 쓸 때 외부 셸에서 "bash -c 'a=1; echo a\$a;'"
확장되는 것을 방지하기 위해 달러 앞에 백슬래시가 필요합니다 .$a
답변2
글쎄요, 저는 작동하는 몇 가지를 찾았습니다( 주의하세요. 이것은 Ubuntu 11.04입니다).
$ sh -c "bash -c 'a=1; echo a\$a \'"
a1
$ sh -c "bash -c 'a=1; echo a\$a;'"
a1
... 첫 번째 작은 따옴표가 이스케이프되지 않고 달러가 이스케이프되는 한 마지막 작은 따옴표가 이스케이프되었는지 여부에 관계없이 작동하는 것 같습니다! 아직도 꽤 헷갈리네요...