함수가 변경하는 매개변수에 따라 달라지는 함수가 있습니다.
나는 내가 할 수 있는 일을 안다:
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 호환 제품을 작성하는 것은 어렵습니다.