필드 분할을 이식적으로 수행하지만 다른 확장은 수행하지 않습니다.

필드 분할을 이식적으로 수행하지만 다른 확장은 수행하지 않습니다.

나는 컴파일러 플래그를 저장할 $variable때 인용되지 않은 확장을 사용 했지만 최근에는 variableglob과 같은 메타 문자가 여전히 확장된다는 것을 알게 되었습니다.*?variable

$ f='*'
$ echo $f
foo.bash

와는 별개로 set -f.

Bash에서 제가 생각할 수 있는 가장 명확한 방법은 read_words배열 이름을 인수로 전달된 문자열의 내용으로 채운 다음 이를 사용하여 ${arr[@]}해당 문자열을 확장하는 함수를 정의하는 것입니다.

#!/bin/bash

count() {
  printf '%s\n' "$#"
}


read_words() {
  IFS=$' \t\n' read -a "$1" <<< "$2"
  return 0
}

read_words arr 'a b *'
count "${arr[@]}"

답변1

set -f와일드카드 없이 필드 분할을 수행하는 가장 편리한 방법입니다.

에서는 bash테스트를 통해 쉘 옵션이 설정되었는지 테스트할 수 있습니다 -o. 그래서 당신은 이것을 할 수 있습니다 :

if [ ! -o noglob ]; then
    set -f
    trap 'set +f' RETURN
fi

이는 쉘 옵션 noglob(의 긴 이름 set -f)의 상태를 감지합니다. 설정하지 않으면 트랩이 설정되어 RETURN설치됩니다. noglob스크립트가 완료된 후 트랩은 셸 옵션의 설정을 해제합니다.스크립트 소스의 경우. 스크립트에 소스가 없으면 트랩은 아무 작업도 수행하지 않습니다.

흥미로운 점: 소스 스크립트는 쉘 함수와 매우 유사합니다.

답변2

Bash에서는 함수에 대한 로컬 set옵션(의 내용 )을 사용할 수 있습니다 . 또는 이식 가능해야 하는 하위 쉘에서 필요한 부분을 실행할 수 있습니다 .$-local -set -f

countwords() { local -; set -f; set -- $1; echo "$#"; }
countwords "a b *"

또는

countwords() ( set -f; set -- $1; echo "$#"; )
countwords "a b *"

관련 정보