지역 변수 할당에 따옴표가 필요합니까?


35

지역 과제의 오른쪽에서 따옴표를 안전하게 생략 할 수 있습니까?

function foo {
    local myvar=${bar}
    stuff()
}

나는 주로 관심이 bash있지만 다른 쉘의 코너 케이스에 대한 정보는 환영합니다.


함수에있는 것처럼 한 줄에 있으면 아무런 차이가 없다고 생각합니다. 과제는 인용 할 필요가 없습니다. mpi-sb.mpg.de/departments/rg1/teaching/unixffb-ss98/…
jirib

답변:


40

따옴표는 필요하다 export foo="$var"또는 local foo="$var"(또는 readonly, typeset, declare및 기타 변수 선언 명령 에) :

  • dash
  • sh의 NetBSD (Almquist 또한 쉘에 기초하여).
  • shFreeBSD의 9.2 또는 그 이상합니다 (참조 9.3에서 변경 )
  • yash
  • zsh5.1 이전 ksh또는 sh에뮬레이션 이전 버전 (또는 단어 분리를 수행 할 export var="$(cmd)"위치 zsh(글 로빙하지 않음))

달리, 변수 확장은 다른 명령에 대한 임의의 인수에서와 같이 단어 분할 및 / 또는 파일 이름 생성에 종속 될 수있다.

그리고 필요하지 않습니다 :

  • bash
  • ksh (모든 구현)
  • shFreeBSD의 9.3 이상의
  • 비지 박스 애쉬 기반 sh(2005 년부터)
  • zsh

에서 zsh분할, + 글로브는에서 제외하고, 매개 변수 확장에 따라 수행되지 않습니다 sh또는 ksh에뮬레이션하지만 분할은 (glob에되지 않음) 명령 치환에 따라 이루어집니다. 버전 5.1 이후, export/ local및 기타 선언 명령은 위의 다른 쉘에서와 같이 이중 키워드 / 내장 명령이 되었으므로sh / ksh에뮬레이션 및 명령 대체에도 인용이 필요하지 않습니다 .

다음과 같은 쉘에서도 인용이 필요한 특별한 경우가 있습니다.

a="b=some value"
export "$a"

또는 더 일반적으로, 만약 어떤이의 왼쪽 =합니다 (포함 =) 인용 또는 일부 확장의 결과 (같은 export 'foo'="$var", export foo\="$var"또는 export foo$((n+=1))="$var"(즉,이 $((...))또한 실제로 인용한다) ...). 또는 다시 말해서 인수가 export유효 변수 할당이 아닌 경우 export.

는 IF export/ local명령 이름 자체가 인용 (심지어 같은 부분에 "export" a="$b", 'ex'port a="$b", \export a="$b", 또는 ""export a="$b"), 주위의 따옴표는 $bAT & T를 제외하고 필요 ksh하고 mksh.

경우 export/ local또는 그 일부가 일부 확장의 결과이다 (처럼 cmd=export; "$cmd" a="$b"심지어 export$(:) a="$b"나 같은 것들에서) dryrun=; $dryrun export a="$b"), 다음 따옴표는 모든 쉘에서 필요하다.

의 경우 > /dev/null export a="$b"따옴표 pdksh및 일부 파생 상품 에 따옴표가 필요합니다 .

를 들어 command export a="$b", 따옴표는 모든 쉘 그러나 필요하다 mkshksh93(약 같은주의 사항으로 command하고 export있지 일부 확장의 결과 인).

작성할 때 어떤 쉘에도 필요하지 않습니다.

foo=$var export foo

(이 구문은 Bourne 쉘과 호환되지만 최신 버전 zsh에서는 sh/ ksh에뮬레이션 에서만 작동합니다 ).

var=value local var셸마다 동작이 다양하므로 사용 하면 안됩니다.

또한 export할당과 함께 사용 하면 cmdin 의 종료 상태 export var="$(cmd)"가 손실 됨을 의미합니다 . 그렇게하는 export var; var=$(cmd)것은 그 문제가 없습니다.

이 특별한 경우에도주의하십시오 bash.

$ bash -c 'IFS=; export a="$*"; echo "$a"' bash a b
ab
$ bash -c 'IFS=; export a=$*; echo "$a"' bash a b
a b

내 조언은 항상 인용하는 것입니다.


3
에 참고 zsh인용 되어 필요한 local foo="$(cmd)"wordsplitting (그러나 파일 이름 세대) 때문 입니다 인용되지 않은 명령 대체 수행 (그러나 인용 부호로 둘러싸이지 않은 매개 변수 확장을위한)을 제외하고는 KSH_TYPESET경우 따옴표가있는, 사용할 수 없습니다 필요. 말이 되나요? 아니? 무엇을하고 있는지 정확히 알지 않는 한 항상 모든 것을 인용하십시오.
Matt

2
@Matt, 나는 당신의 결론을 좋아합니다. : D 그것의 재미, 내가 쉘 스크립트의 배운 내용의 대부분이 stackexchange에서 온, 그래서 그 실현하지 않았다 항상 변수를 인용 입니다 하지 스크립트 작성자 사이에 상식. 나는 사람이 작성한 생산 스크립트 기존의 할 고치를 많이 가지고 찾는거야 하지 않았다 인용을하고, 하지 않았다 가 .... 뭘하고 있었 정확히 알고
와일드 카드

3

나는 일반적으로 공백과 같은 문자가있을 수있는 변수의 사용법을 인용합니다. 그렇지 않으면 다음과 같은 문제가 발생합니다.

#!/bin/bash

bar="hi bye"

function foo {
  local myvar=${bar}
  printf "%s\n" $myvar
  printf "%s\n" "$myvar"
}

foo

대입에서 변수의 사용법에는 따옴표가 필요하지 않지만 따옴표와 같이 사용하려고 printf할 때 따옴표가 필요합니다.

  printf "%s\n" "$myvar"

참고 : 변수 $IFS는 구분 기호 문자를 제어합니다.

IFS    The  Internal  Field  Separator that is used for word splitting after 
       expansion and to split lines into words with the read builtin command. 
       The default value is ``<space><tab><newline>''.

Bash에서 디버깅을 활성화하면 뒤에서 무슨 일이 일어나고 있는지 확인할 수 있습니다.

$ bash -x cmd.bash 
+ bar='hi bye'
+ foo
+ local 'myvar=hi bye'
+ printf '%s\n' hi bye
hi
bye
+ printf '%s\n' 'hi bye'
hi bye

위에서 우리는 변수 $bar가 잘 전달 되었음을 알 수 있습니다. $myvar그러나 $myvar우리가 $myvar사용하려고 할 때 우리는 그것을 사용했을 때 의 내용을인지 해야했습니다.


2
단어 분할은 인용되지 않은 변수의 유일한 문제는 아니지만 파일 이름 생성 (일명 globbing)도 고려해야합니다 (그러나 둘 다 변수 할당 및 / bash및 특수 내장 ksh에 적용되지는 않습니다 ). localtypeset
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.