args 및 "종료되지 않은 인용 문자열"/"예기치 않은 EOF"에서 읽은 명령을 사용하여 sh(대시)에서 bash 호출

args 및 "종료되지 않은 인용 문자열"/"예기치 않은 EOF"에서 읽은 명령을 사용하여 sh(대시)에서 bash 호출

기록을 바로잡고 싶었습니다. 저는 매우 간단한 작업을 시도하고 있습니다. 환경 변수를 설정한 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-ca=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

...첫 번째 작은 따옴표가 이스케이프되지 않고 달러도 이스케이프되는 한 마지막 작은 따옴표가 이스케이프되었는지 여부에 관계없이 작동하는 것처럼 보입니다! 아직도 혼란스러워요...

관련 정보