왜 쉘 스크립트에서 큰 따옴표와 백 따옴표를 사용합니까?


5

이 스크립트 mysql 백업 스크립트를 보고 있는데 명령 이름에 백틱과 큰 따옴표를 모두 사용해야하는 이유를 이해하지 못합니까?

379 WHICH="`which which`"
380 AWK="`${WHICH} gawk`"
381 LOGGER="`${WHICH} logger`"
382 ECHO="`${WHICH} echo`"
383 CAT="`${WHICH} cat`"
384 BASENAME="`${WHICH} basename`"
385 DATEC="`${WHICH} date`"
386 DU="`${WHICH} du`"
387 EXPR="`${WHICH} expr`"
388 FIND="`${WHICH} find`"
389 RM="`${WHICH} rm`"
390 MYSQL="`${WHICH} mysql`"
391 MYSQLDUMP="`${WHICH} mysqldump`"
392 GZIP="`${WHICH} gzip`"
393 BZIP2="`${WHICH} bzip2`"
394 CP="`${WHICH} cp`"
395 HOSTNAMEC="`${WHICH} hostname`"
396 SED="`${WHICH} sed`"
397 GREP="`${WHICH} grep`"

최신 정보:

입니다

"`${WHICH} gawk`"

거의 같은

"${${WHICH} gawk}"

답변:


10

WHICH="`which which`"정확히 동일하다 WHICH=`which which`거나 WHICH=$(which which)또는에 WHICH="$(which which)". 이들 모두는 명령을 실행 which which하고 출력에서 ​​문자열로 출력을 캡처하여 출력 WHICH에서 마지막 줄 바꿈을 제거합니다. 마찬가지로 AWK="`${WHICH} gawk`"쓸 수 있습니다 AWK=`$WHICH gawk`.

일반적으로 결과에 공백 또는 셸 와일드 카드 ( ) 가 포함 된 경우 명령 대체 ( `command`또는 $(command))는 큰 따옴표로 묶어야합니다 *?[\. 변수 대체 ( $foo또는 ${foo}) 와 같은 명령 대체 결과에 단어 분할 및 파일 이름 생성 (일명 globbing)이 발생하기 때문입니다. 그러나 이는 간단한 변수 할당에는 적용되지 않습니다. 컨텍스트에는 단일 단어가 필요하므로 대체 결과는 그대로 사용됩니다. 따라서 할당은 변수 및 명령 대체를 큰 따옴표로 묶어야하는 일반적인 규칙의 예외입니다. (이 예외는 확장되지 않습니다export var="$value"그러나 큰 따옴표를 요구하는 것은 합리적입니다. 그러나 항상 큰 따옴표를 사용하는 것은 합리적인 쉘 프로그래밍 관행입니다. 반드시 필요한 경우에만 사용하지 말고 반드시 필요한 경우에만 따옴표를 생략하십시오.

(경우에 따라) which which공백이나 와일드 카드가 포함 된 경로를 반환하는 경우 ${WHICH}아래 줄에 이중 따옴표로 묶어야합니다.

AWK="`"${WHICH}" gawk`"
AWK=`"${WHICH}" gawk`
AWK="$("${WHICH}" gawk)"
AWK=$("${WHICH}" gawk)

중첩 된 따옴표를 안에 넣기가 어렵 기 때문에을 (를) 사용하는 $(…)것이 좋습니다 . 그러나 아주 오래된 쉘은 인식하지 못 하므로 이전 시스템에서 실행해야하는 스크립트에는 필요합니다.`…``…`$(…)`…`

$ VAR vs $ {VAR} 및 인용 여부 도 참조하십시오.


음. 틀린 점 있으면 지적 해주세요. 원본 스크립트 작성자가 ECHO에 대한 별칭을 만들 필요가없는 것처럼 보입니다. 내장 된 bash 명령이기 때문입니까? - 권리?
Stann

4
@Andre : 예, ECHO완전히 쓸모가 없습니다. 그러나 which여기에 대한 모든 호출 은 쓸모가 없습니다. 왜냐하면 모든 스크립트는 명령을 호출하기 때문 PATH입니다. 인용문도 꺼져 있습니다 :이 변수의 정의에는 큰 따옴표가 있습니다. 이곳에서는 차이가 없지만 변수를 사용할 때 (때로는 심지어조차도 있습니다 eval). 명령 이름에 특수 문자를 사용하여이 스크립트를 호출해서는 안됩니다 (또는에 $PASSWORD있지만이 방법을 사용하는 것은 좋지 않습니다).
Gilles

예-나는 그 회피에 대해 머리를 긁고있었습니다.)-또한 내부 쉘 변수와의 충돌을 피하기 위해 일반 변수를 소문자로 사용해야합니다. 그리고 그들은 그 대본의 모든 곳에 대문자입니다. 음 .. 오 잘. 이 같은 것들이 나 같은 bash 초보자를 방해합니다. 도와 주셔서 감사합니다!
Stann

IMHo-그 스크립트는 스크립트에 대해 약간 과장되어 있습니다-mysql dbs backup--동의하십니까?
Stann

0

백틱이 공백이있는 문자열을 반환하는 경우 따옴표는 완전한 단일 값이 변수에 지정되도록합니다.


5
일반적으로 명령 대체에 큰 따옴표를 사용하는 것이 좋지만, 이것이 필요하지 않은 몇 가지 사례 중 하나입니다. .
Gilles

1
사실 일 수도 있지만, 한 가지 특정 스크립트가 왜 그렇게하는지에 대한 의문이 있었으며, 이것이 원래 저자가 생각했던 것입니다. 옳고 그른 것, 그것은 추론 일 것입니다. 당신이 말했듯이, 그것은 일반적으로 좋은 생각 이며이 맥락에서 해를 끼치 지 않기 때문입니다.
Keith

1
즉, 조언이 나쁜 이유입니다. 그것들을 유익한 경우에 사용하고, 그렇지 않은 경우 생략하면 구별에 대한 학습을 ​​장려합니다.
사용자가 알 수 없음

1
우리 중 일부는 조개류를 배우는 것보다 시간과 더 좋은 일을합니다. 단점이없는 안전한 방법으로하는 것은 훌륭한 조언입니다.
Keith

0

backtick 연산자는 "backticks 사이의 영역을 backticks 안에있는 명령의 출력으로 대체합니다. 큰 따옴표는 출력에 공백이 포함 된 경우 해당 변수는 전체 결과뿐만 아니라 전체 결과로 설정됩니다. 첫 번째 공백.

예를 들어 어떤 이유로 grep 명령이 '/ usr / local / bin / real grep'인 경우,

GREP=`which grep`

GREP에는 "/ usr / local / bin / real"이 포함됩니다

반면에

GREP="`which grep`"

GREP에는 "/ usr / local / bin / real grep"이 포함됩니다.

이러한 명령의 경로에 공백이 포함되어 있지는 않지만 셸 스크립트에서 변수에 할당 할 때 항상 큰 따옴표를 사용하는 것이 좋습니다.


3
일반적으로 명령 대체에 큰 따옴표를 사용하는 것이 좋지만, 이것이 필요하지 않은 몇 가지 사례 중 하나입니다. .
Gilles

1
테스트 스크립트를 실행 한 후 옳은 것 같습니다. 실행 후 TEST = echo testing 123, $ TEST에는 "testing 123"이 포함됩니다. 그래도 변수 할당에 큰 따옴표를 포함시키는 것이 좋습니다.
tak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.