함수에 부울 플래그를 전달하시겠습니까?

함수에 부울 플래그를 전달하시겠습니까?

함수가 변경하는 매개변수에 따라 달라지는 함수가 있습니다.
나는 내가 할 수 있는 일을 안다:

function foo {  
  PARAM1=$1  
  PARAM2="$2"  
  VAR=$3  
  if[[ -z "$VAR" ]]; then  
   # code here  
  else  
   # other code here  
  fi  
}  

Bash에 더 적절한 방법이 있는지 궁금합니다. 이것은 효과가 있지만 나는 다음과 같은 것을 원하지 않습니다

foo "x" "y" "blah"  
foo "x" "y" "true"  
foo "y" "y" "1"

모든 것이 동일합니다.

Bash를 사용하는 더 좋은 방법이 있나요?

답변1

함수에 명령줄 옵션을 제공할 수 있습니다. 인수 없이 명령줄 옵션을 사용하는 것은 쉘 스크립트, 쉘 함수 및 유틸리티에 바이너리/부울 값("on/off", "true/false", "enable/disable")을 제공하는 일반적인 방법입니다.

foo () {
    local flag=false
    OPTIND=1

    while getopts 't' opt; do
        case $opt in
            t) flag=true ;;
            *) echo 'Error in command line parsing' >&2
               exit 1
        esac
    done
    shift "$(( OPTIND - 1 ))"

    local param1="$1"
    local param2="$2"

    if "$flag"; then
        # do things for "foo -t blah blah"
    else
        # do things for "foo blah blah"
    fi
}

이 옵션은 -t사용자에게 부울 플래그로 표시됩니다. 이를 사용하면 flag함수가 내부적으로 true(기본값을 로 변경 false)로 설정됩니다. 이 -t옵션은 함수의 첫 번째 매개변수로 사용됩니다.

이 함수를 호출하려면 다음을 사용할 수 있습니다.

foo "some value" "some other value"

또는

foo -t "some value" "some other value"

후자의 호출은 flag함수의 변수를 로 설정합니다 true.

답변2

일반적으로 말하면

일반적으로 부울 값을 함수에 전달하는 것은 어떤 언어에서도 읽을 수 없습니다. 예를 들어 calculate_interest 5y 4% true. 독자는 무엇이 진짜인지 궁금해하게 됩니다.

따라서 열거형을 사용하십시오: { per_month, per_year }. 이제 당신은 그것을 할 수 있습니다 calculate_interest 5y 4% per_year. 이것이 더 읽기 쉽습니다.

배쉬에서

Bash는 정적으로 유형이 지정되지 않았으므로(또는 강력한 유형이 있거나 유형 시스템이 전혀 없음) 다양한 값을 전달할 수 있습니다. 한 사람은 이 길을 택할 것이고, 다른 사람은 그렇지 않을 것이다. 우리는 같은 길을 따라가는 다양한 가치를 원하지 않습니다.

따라서 입력이 허용되는 두 값 중 하나인지 확인하는 코드를 추가하세요. 함수 시작 부분에 이 작업을 수행합니다. 작업을 마친 후 1/2을 종료하고 싶지는 않습니다.

부울 값을 사용하는 함수를 호출해야 하는 경우 수행할 작업

누군가 내 조언을 따르지 않았으므로 부울 값을 사용하여 함수를 호출해야 합니다. 코드를 읽기 쉽게 만들기 위해 무엇을 할 수 있나요?

  • 언어(예: Python)에서 명명된 매개변수(예: )를 허용하는 경우 해당 매개변수 calculate_interest 5y 4% per_year=True를 사용하세요. 도움이 되겠지만 의미를 말해주지는 않습니다 calculate_interest 5y 4% per_year=False.
  • 언어에 명명된 매개변수가 없는 경우 유일한 옵션은 읽을 수 없는 코드(옵션 아님)를 허용하거나 함수를 읽기-쓰기 함수로 래핑하는 것입니다.

답변3

다음 형식을 따르는 것이 좋습니다.

foo() {
  # Limit scope of variables
  local 'opt1' 'opt2' 'opt3' 'operands'

  # Default values
  opt1='default1'
  opt2='default2'
  opt3='false'
  operands=()

  # Arguments handling
  while (( ${#} > 0 )); do
    case "${1}" in
      ( '--opt1='* ) opt1="${1#*=}" ;;           # Handles --opt1
      ( '--opt2='* ) opt2="${1#*=}" ;;           # Handles --opt2
      ( '--opt3='* ) opt3="${1#*=}" ;;           # Handles --opt3
      ( '--' ) operands+=( "${@:2}" ); break ;;  # End of options
      ( '-'?* ) ;;                               # Discard non-valid options
      ( * ) operands+=( "${1}" )                 # Handles operands
    esac
    shift
  done

  ...
}

이렇게 하면 함수가 더욱 강력해지고 읽기 쉬워집니다.

$ foo
Options:
  opt1: [default1]
  opt2: [default2]
  opt3: [false]
$ foo --opt1='value1' --opt2='value2' --opt3='true' 'foo' 'bar' 'baz'
Options:
  opt1: [value1]
  opt2: [value2]
  opt3: [true]
Operands:
  1: [foo]
  2: [bar]
  3: [baz]

이점:

  • 읽고 이해하기 쉽습니다.
  • 구문은 일반적인 명령줄 유틸리티와 유사합니다.
  • 호환성을 유지하면서 더 많은 옵션을 쉽게 추가할 수 있습니다.

결점:

  • 작고 간단한 스크립트에는 과잉일 수 있습니다.
  • 긴 옵션과 피연산자를 처리하기 위해 이식 가능하고 POSIX 호환 제품을 작성하는 것은 어렵습니다.

관련 정보