와일드카드로 작성되고 공백을 포함하는 경로를 변수에 저장하는 방법

와일드카드로 작성되고 공백을 포함하는 경로를 변수에 저장하는 방법

상황은 다음과 같습니다(저는 Mac, OS X El Capitan을 사용하고 있습니다).

# This works:

$ cd /Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates/;

# These do not work:

$ INSTALL_DIR=/Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates;
$ cd $INSTALL_DIR
# Moves me here: /Applications/Adobe

$ cd "$INSTALL_DIR"
-bash: cd: /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates: No such file or directory

$ cd "${INSTALL_DIR}"
-bash: cd: /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates: No such file or directory

$INSTALL_DIR내 목표는 다음과 같이 사용하는 것입니다 tar.

$ tar -xz $SOURCE_ZIP --strip-components 1 -C $INSTALL_DIR "*.ait";

불행히도 (대상 디렉토리로 변경) 은 ;의 공백을 -C좋아하지 않습니다 . $INSTALL_DIR따옴표를 사용하면 제대로 작동하지 않습니다 *.

이 상황을 처리하는 우아한 방법이 있습니까?

답변1

*가 인용되지 않으면 쉘은 명령을 실행하기 전에 인수 목록을 확장합니다. 확장된 인수 목록을 프로그램에 전달합니다.

*가 인용된 문자열에 나타나면 프로그램에 전달되기 전에 쉘에 의해 확장되지 않습니다.

경로를 확장하여 다른 변수에 할당한 다음 매개변수로 전달할 때 두 번째 변수를 참조해 보세요.

답변2

문제는 tar가 아니라 쉘 코드에 있습니다. 이 옵션에 대한 인수는 -C와일드카드 패턴이 아닌 경로여야 합니다. 이 명령을 사용하면 똑같은 문제가 발생합니다 cd.

와일드카드 패턴을 변수에 저장했습니다 INSTALL_DIR. 을 작성할 때 -C $INSTALL_DIR"split+glob" 연산자가 적용됩니다. 즉, 변수의 값을 가져와서 공백으로 분할하고 각 단어를 와일드카드 패턴으로 해석한 다음 확장합니다. 여기서 변수의 값은 , , /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates세 단어로 나누어져 있는데 , 중간 단어에 와일드카드 문자( )가 포함되어 와일드카드 패턴으로 해석되지만, 일치하는 파일이 없으므로 패턴은 그대로 유지됩니다. 이는 옵션에 대한 인수를 문자열 로 만들고 명령에는 두 개의 추가 인수인 및 가 있습니다 ./Applications/AdobeIllustrator*/CoolExtras.localized/en_US/Templates*-C/Applications/AdobetarIllustrator*/CoolExtras.localized/en_US/Templates

큰따옴표를 사용하는 경우 이는 "$INSTALL_DIR"단지 변수의 값일 뿐입니다 INSTALL_DIR. *한 번도 확장되지 않았기 때문에 여전히 내부에 있습니다.

경험상 와일드카드는 두 단어 이상이 필요한 상황에서 확장됩니다. 결국 일반적으로 와일드카드 패턴은 여러 파일과 일치합니다. 결과가 단일 문자열일 것으로 예상되므로 할당 오른쪽은 와일드카드 확장을 억제합니다. 목록을 얻으려면 문자열 변수 대신 배열 변수에 할당하십시오.

INSTALL_DIRS=(/Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates)

여러 버전의 Illustrator가 설치되어 있는 경우 배열 요소가 여러 개 있을 수 있습니다. 마지막 요소를 살펴보겠습니다.

INSTALL_DIR=${INSTALL_DIRS[$((${#INSTALL_DIRS}-1))]}

Now는 INSTALL_DIR기존 파일의 경로입니다(와일드카드가 일치한다고 가정). 정상적으로 사용할 수 있습니다(즉, 큰따옴표 안에 확장할 수 있습니다).

tar -xz "$SOURCE_ZIP" --strip-components 1 -C "$INSTALL_DIR" "*.ait"

관련 정보