스크립트에서 zenity의 공백을 사용하려고 할 때 발생하는 문제 [중복]

스크립트에서 zenity의 공백을 사용하려고 할 때 발생하는 문제 [중복]

이것은 터미널에서 직접 실행되지만 잘 작동합니다.

zenity --info --text "pure info" --title "get info"

그런데 이 스크립트가 작동하지 않습니다. 무슨 일이 일어나고 있는 걸까요?

!/bin/bash
ZEN="--info --text \"pure info\" --title \"get info\""
zenity $ZEN

스크립트는 "텍스트의 정보 및 제목의 "jeevan"을 출력합니다. 나머지는 건너뛰는 것입니다.
큰따옴표 안의 공백(특수문자)이 그 특별한 의미를 잃어버리기 때문일까요?

답변1

차이점은 명령이 zenity첫 번째 경우에는 여러 인수를 볼 수 있지만 두 번째 경우에는 하나의 인수(많은 공백 포함)만 볼 수 있다는 것입니다.

다음 awk프로그램을 사용하면 쉘이 인수를 확장하는 내용을 빠르게 출력할 수 있습니다. 문제가 발생하면 zsh문제를 재현할 수 있습니다.

% awk 'BEGIN {for (i in ARGV) print "ARGV["i"] =", ARGV[i]}' $ZEN                                               
ARGV[0] = awk
ARGV[1] = --info --text "pure info" --title "get info"

그리고 bash그것은 다음과 같아야 합니다(인용된 문자열은 단어로 분할되어 있습니다).

$ awk 'BEGIN {for (i in ARGV) print "ARGV["i"] =", ARGV[i]}' $ZEN
ARGV[0] = awk
ARGV[1] = --info
ARGV[2] = --text
ARGV[3] = "pure
ARGV[4] = info"
ARGV[5] = --title
ARGV[6] = "get
ARGV[7] = info"

이 동작을 처리하는 쉘 토큰화 옵션이 있어야 합니다.

그러나 이것은 작동합니다:

set -- --info --text "pure info" --title "get info"
zenity "$@"

편집하다:

쉘의 단어 분리 기능은 기본적으로 약간 어리석습니다. bash위 예의 동작을 참조하십시오. "pureinfo"두 개의 별도 단어입니다. 명령줄 옵션을 구문 분석할 때 이는 성가신 일이므로 다음은 매뉴얼의 특수 매개변수 섹션 "$@에서 인용한 내용 입니다.bash

   @      Expands  to  the positional parameters, starting from one.  When
          the  expansion  occurs  within  double  quotes,  each  parameter
          expands to a separate word.  That is, "$@" is equivalent to "$1"
          "$2" ...

일반적인 변수 확장을 특별히 처리하는 방법을 찾지 못했지만 $@트릭이 있을 수 있습니다.

set명령은 위치 매개변수 $1, $2... 를 설정합니다. 따라서 위치 인수의 "모두 제공" 버전 $@도 사용할 수 있습니다.

답변2

이 문제를 해결하는 한 가지 방법은 eval문자열 내부의 따옴표가 구문 분석되도록 전체 표현식을 평가하는 것입니다.

eval zenity "$ZEN"

그런데 변수 정의에서 큰따옴표를 이스케이프 처리하는 대신 작은따옴표를 사용할 수도 있습니다.

ZEN='--info --text "pure info" --title "get info"'

#그건 그렇고, 당신이 이전에 놓쳤던 것 !/bin/bash.

zsh를 사용하는 경우 또 다른 접근 방식은 플래그와 함께 쉘 구문 분석을 사용하여(인용 부호 고려) 인수를 단어로 분할하는 것 z입니다. 즉:

zenity "${(z)ZEN}"

관련 정보