큰따옴표 이스케이프 방지

큰따옴표 이스케이프 방지

Bash 스크립트에서 일부 명령을 실행하고 싶습니다.
이제 작은따옴표를 사용하면 변수가 값이 아닌 리터럴로 처리됩니다.
예를 들어 이렇게 하는 것은 큰따옴표를 이스케이프 처리하여 모든 것을 엉망으로 만들지 않고 따옴표와 큰따옴표의 혼합을 처리하는 방법과 다릅니다 ls "$SOME_DIR". 예를 들어 다음과 같은 것을 확인하는 방법은 다음과 같습니다. ls '$SOME_DIR'

ssh server.com "mkdir \"/foo/bar/"$final"\""  

명령이 길어질수록 읽을 수 없고 쉽게 손상되기 때문에 이러한 모든 탈출을 어떻게 피할 수 있습니까?

답변1

여러 번 사용한 후에 가장 간단한 해결책은 다음 heredocsherestrings같습니다.

ssh server.com "mkdir '/foo/bar/$final'"

예, 에서처럼 작은따옴표에도 불구하고 bash변수 대체가 계속 발생합니다 .$finalecho "test'$final'"

$final참고: @muru가 지적했듯이 작은따옴표가 포함된 경우에는 작동하지 않습니다.

답변2

반대 참조, (큰따옴표 안의 작은따옴표그 반대로), 이스케이프 대신 사용할 수 있습니다. 이스케이프 문자를 사용하지 않거나여기에 파일echo, 다음을 사용하여 이 텍스트를 표시하는 방법을 고려하십시오 .

그는 뒤도 돌아보지 않고 “말도 안돼”라고 말했다.

큰따옴표나 작은따옴표로 묶으면 작동하지 않습니다. 반대 따옴표를 번갈아 사용하면 작동합니다.

echo "He didn't look back, and said "'"It can'"'t be helped."'"'

산출:

He didn't look back, and said "It can't be helped."

불행히도 위의 내용은 echo탈출뿐만 아니라 읽기도 어렵습니다.

시각적인 단조로움을 줄이기 위해 반대 따옴표를 사용하고 필요에 따라 둘 다 이스케이프 처리하는 것이 좋습니다.

echo "He didn't look back, and said \"It can't be helped.\""

코드에 적용:

ssh server.com 'mkdir "'"/foo/bar/$final"\"

$final포함 되더라도 '.

견적을 확장하면 다음과 같습니다.

  1. 'mkdir "', 공백과 왼쪽 큰따옴표가 유지됩니다.
  2. "/foo/bar/$final"$final시작되기 전의 내용을 반환합니다 ssh.
  3. \"큰따옴표를 닫고 디렉터리 이름을 유지합니다.ssh

답변3

실제 요구 사항은 로컬로 명령을 보내기 전이나 원격으로 명령을 보낸 후 변수를 확장하려는 위치/시기에 따라 많이 달라집니다. 두 경우 모두 유효합니다. 어느 쪽이든, 명령이 한 줄에 들어갈 경우 <<<각각 큰따옴표나 작은따옴표를 사용하여 명령을 리디렉션하는 것이 좋습니다.

1. 명령을 보내기 전에 변수를 구문 분석합니다.

final="defined_locally"; ssh server.com <<<"final="defined_remotely" ;mkdir /foo/bar/"$final" "

2. 명령을 보낸 후 변수를 구문 분석합니다.

final="defined_locally"; ssh server.com <<<'final="defined_remotely"; mkdir /foo/bar/"$final" '

첫 번째 항목이 생성됩니다.

/foo/bar/define_locally

두 번째는 만들 것입니다.

/foo/bar/define_remotely

원격 서버의 디렉터리

보시다시피, 하나의 명령에 로컬 및 원격 정의 변수를 혼합하기 전까지는 두 경우 모두 이스케이프가 필요하지 않습니다.

고쳐 쓰다:

<<<

엄밀히 말하면 리디렉션이 아닙니다.여기 문자열

업데이트 2:

지적해주신 @Rastapopoulos에게 감사드립니다.

Pseudo-terminal will not be allocated because stdin is not a terminal 명령 실행에 수반되는 메시지

아무런 피해가 없더라도

답변4

이것은 내장된 작업입니까 printf?

ldo@theon:~> f='He didn'\''t look back, and said "It can'\''t be helped."'
ldo@theon:~> echo "$f"
He didn't look back, and said "It can't be helped."
ldo@theon:~> ssh hypatia echo "$f"
bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file
ldo@theon:~> ssh hypatia echo $(printf %q "$f")
He didn't look back, and said "It can't be helped."

관련 정보