이 Bash 스크립트를 호출 할 때 파일 인수에 따옴표가 필요한 이유는 무엇입니까?


13

Bash 스크립팅을 처음 접했습니다. "테스트 스크립트"가 있는데, 고급 / 유용한 스크립트의 기초로 사용했습니다.

#!/bin/bash
files=$1
for a in $files
do
    echo "$a"
done

따옴표없이 이것을 호출하면 디렉토리에서 하나의 파일을 선택합니다.

testscript *.txt

그러나 따옴표로 호출하면 올바르게 작동하고 모든 텍스트 파일을 선택합니다.

testscript '*.txt'

무슨 일이야?


아주로 매우 명확하고이 문제를 해결하는 올바른 방법은 다음을 수행하는 것입니다 for a in "$@"; do(또는 for a; do의 외부 쉘에 글 로빙 따라서 떠나, 스크립트에서) 따옴표를 생략 할 수 없습니다.
Charles Duffy


이것은 가치가 있습니다. guide.bash.academy
vascowhite

답변:


29

프로그램을 호출 할 때

testscript *.txt

그런 다음 은 확장을 수행하고 모든 값을 해결합니다. 따라서 효과적으로 프로그램을 호출 할 수 있습니다.

testscript file1.txt file2.txt file3.txt file4.txt

이제 프로그램은보고 $1만 작동합니다 file1.txt.

명령 행에 인용하면 리터럴 문자열 *.txt을 스크립트에 전달하게 됩니다 $1. 귀하의 for루프는 다음을 확장합니다.

일반적으로 이와 같은 스크립트 에서는 사용 "$@"하지 않을 것 $1입니다.

이것은 CMD 스크립팅에서 온 사람들에게 "gotcha"입니다. 명령 쉘은 알려진대로 글 로빙을 수행하지 않고 항상 리터럴 문자열을 전달합니다.


6
그냥 사용 (위의 대답의 저자가 아닌 다른 사람들을 위해) 명확하게 "$@"(반대 $@$1 $2 $3) 각 파일 이름이 인용되는 원인이됩니다 "file1.txt" "file2.txt"경우 등 file1.txt이 의미가 있지만,이 경우 my file.txt의 인용은 중요한 쉘을 방지하기 위해 파일 이름을 파싱하여 두 개의 파일 이름 (이름 my과 이름)으로 바꿉니다 file.txt. 언젠가는 매우 불행하지 않도록 항상 사용자 입력과 글로벌 확장을 인용하십시오.
세스 로버트슨

2
그리고 이것은 이론적 인 문제가 아닙니다-Mac OS X은 인수를 제대로 인용하지 않고 일부 상황에서 사람들의 하드 드라이브를 삭제하는 업데이트 스크립트와 함께 제공되었습니다.
푹신한

2
@fluffy, 그것에 대한 링크가 있습니까?
와일드 카드

@Wildcard 불행히도 나는 그것에 관한 기사를 찾을 수 없지만 기술 세계에서는 큰 뉴스였습니다. 애플이 여전히 유닉스 배포자가되던 시절에 2003/2004 년쯤이라고 말하고 싶습니다.
푹신한

1
@wildcard 아, 찾았 어! xlr8yourmac.com/OSX/itunes2_erased_drives.html- 실제로 범인이었던 iTunes 업그레이드 스크립트였습니다.
푹신한

7

따옴표없이 셸 *.txt은 스크립트를 호출하기 전에 확장 되므로 $1확장 된 첫 번째 파일 만 확장됩니다. 모든 txt파일은 그 시점에서 스크립트에 대한 인수입니다 (너무 많지 않다고 가정).

따옴표를 사용하면 문자열이 스크립트로 확장되지 않고 전달되므로 for원하는대로 확장 할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.