터미널에서 "set -u"를 사용해야 합니까? git의 자동 완성 기능이 중단되는 이유는 무엇입니까?

터미널에서 "set -u"를 사용해야 합니까? git의 자동 완성 기능이 중단되는 이유는 무엇입니까?

set -u(에 해당 set -o nounset)을 추가했지만 .bashrc이제 변수가 설정되지 않았다는 오류로 인해 일부 탭 자동 완성이 실패합니다. 한 가지 예는 git자동 완성입니다.

이것은 자동 완성 버그입니까, 아니면 git일반적으로 대화형 터미널에서 사용하는 것은 나쁜 생각입니까? set -u자동 완성 기능을 손상시키지 않고 자신을 보호할 수 있는 다른 방법이 있습니까?

(Windows/cygwin 및 RHEL에서 "git bash"를 사용하여 동일한 문제가 발생했습니다.)

답변1

set -uBourne 쉘 또는 보다 구체적으로 set -o nounsetKorn 쉘(둘 다 POSIX)에서 나오는 것은 코드에서 초기화된 변수의 오타나 사용을 감지하기 위한 프로그래밍 도구에 가깝습니다.

이는 프로그래밍 스타일 선택입니다. 일단 설정되면 코드가 설정되지 않은 변수를 역참조하도록 할 수 없습니다. 즉, 코드를 다르게 작성해야 합니다.

예를 들어 다음과 같은 작업을 수행할 수 없습니다.

if [ -n "$TERM" ]; then
  echo running in a terminal
fi

use 대신 nounsetwith 문제를 해결해야 합니다 .${TERM-}$TERM[[ -v TERM ]]

errexit일부는 or failglob또는 와 같은 대부분의 다른 옵션과 함께 사용되며 , pipefail이는 셸 작동 방식을 변경하고 코드 작성자는 코드를 조정해야 합니다.

이제 대화형 셸에서는 다른 사람이 작성한 코드를 사용하지 않으면 문제가 되지 않습니다.

문제는 bash가 emulate -L제3자 함수가 자체 코드에 대해 로컬로 합리적인 옵션 기준을 명시적으로 요청할 수 있는 zsh와 동일하지 않다는 것입니다.

zsh에서 완료 코드는 일반적으로 다음을 수행합니다.

some-completion-function() {
  emulate -L zsh # default set of options in the zsh emulation set locally
  set -o extendedglob -o errreturn # additional local options as needed

  code here not impacted by the users options
}

bash에는 동등한 기능이 없지만 bashhas (ash의 최신 버전 local -)는 설정되는 옵션에 대한 로컬 범위를 설정할 수 있지만 set. shopt동등한 것이 없기 때문에 emulate모든 옵션을 기본값으로 하드코딩해야 하며 그 목록은 bash 버전에 따라 변경됩니다.

bash_completion(bash 자체와 별도의 프로젝트)은 기본 옵션을 전역적으로(그 자체뿐만 아니라) 변경하며 사용자가 이를 변경하지 않을 것으로 예상한다는 점을 언급할 가치가 있습니다. 예를 들어, extglob및 를 설정합니다 progcomp.

예를 들어 옵션을 임시로 설정하거나 이전 설정을 변수에 저장하고 나중에 복원하여 옵션을 어색하게 설정하는 경우 verbose도 있습니다 noglob.nullglob

Bash 및 zsh에는 코드가 구문 분석되는 방식에 영향을 미치는 옵션도 있으므로 완료 코드(또는 타사 코드)가 로드된 후에 설정해야 합니다. zsh에서 대부분의 완료 코드는 다음과 같습니다.자동 로드처음 사용할 때 자동 로딩은 사용자의 옵션이나 별칭( 옵션 -z도 포함 )과 독립적으로 수행될 수 있지만 bash에는 이에 상응하는 기능이 없습니다.-Uautoload

따라서 기본값이 변경되면 bash가 완료되지 못하게 하는 많은 옵션이 있다는 것을 알게 될 것입니다( , noglob, nounset, errexit등 ). IIRC에서 값을 변경하면 문제가 발생할 수도 있습니다(또는 적어도 익숙해지면). 이들 중 일부는 bash_completion에서 버그로 간주될 수 있지만, 대부분의 경우 이를 비난할 수는 없습니다. 문제는 bash가 다양한 옵션 세트의 요구 사항에 대처할 수 있는 도구를 갖고 있지 않기 때문입니다.errreturnfailglob$IFS

따라서 옵션을 변경하는 경우 셸에서 사용되는 일부 타사 코드가 실패할 수 있다는 점에 대비하세요.

관련 정보