9 개의 인수를 가진 아래 함수에서 :
SUM() {
echo "The sum is $(($1+$2+$3+$4+$5+$6+$7+$8+$9))"
}
다음 (3..9)에 대한 두 번째 인수를 선택적 인수 로 만들고 싶습니다 .
두 개의 인수로 함수를 호출하면 오류가 발생합니다.
SUM 3 8
bash: 3+8+++++++: syntax error: operand expected (error token is "+")
참고 BOLD : 첫 번째 인수와 두 번째 인수는 강제 인수 이며 기능에 대해 선택 사항이 아닙니다. 다음 인수에 대한 두 번째 인수 만 선택적이며 2 args 미만의 함수를 호출하면 함수가 결과를 반환하지 않아야합니다.
답변
공백이있는 인수를 전달하지 않는 경우 :
sum() {
[[ -n $2 ]] && echo $(( $(tr ' ' '+' <<<"$@") ))
}
효과:
$ sum 1 2 3
6
설명:
<<<"some string"
"some string"
입력 으로 만 피드 합니다. 이를 속기라고 생각하십시오echo "some string" |
. 이를 Here String 이라고합니다 ."$@"
공백으로 구분 된 모든 위치 매개 변수로 확장됩니다. 와 같습니다"$1 $2 ..."
.- 따라서
tr ' ' '+' <<<"$@"
출력"$1+$2+$3..."
은 outer에 의해 평가됩니다$(( ))
. [[ -n $2 ]]
두 번째 매개 변수가 비어 있지 않은지 테스트합니다. 으로 교체 할 수[[ -n $2 ]] &&
있습니다[[ -z $2 ]] ||
.
또 다른 방법:
sum() {
[[ -n $2 ]] && (IFS=+; echo $(( $* )))
}
설명:
$*
$@
매개 변수가 공백으로 구분되지 않고 Internal Field Separator (IFS
) 의 첫 문자로 구분된다는 점을 제외하고 는 같습니다 . 를 사용하면IFS=+
“$ 1 + $ 2 + …”로 확장됩니다. $ *와 $ @의 차이점 은 무엇입니까?를 참조하십시오 .IFS
메인 쉘이 영향을받지 않도록 서브 쉘 (주변 괄호에주의)을 설정 했습니다.IFS
기본적으로 :\t\n
(공백, 탭, 줄 바꿈)입니다.local
변수 를 사용하는 대신 사용할 수 있습니다.
이제 귀하의 질문에 대답하십시오 :
모든 변수 또는 매개 변수에 기본값을 사용할 수 있습니다 . 어느 한 쪽:
SUM() {
echo "The sum is $(($1+$2+${3:-0}+${4:-0}+${5:-0}+${6:-0}+${7:-0}+${8:-0}+${9:-0}))" || false
}
또는:
SUM() {
echo "The sum is $(($1+$2+${3:=0}+${4:=0}+${5:=0}+${6:=0}+${7:=0}+${8:=0}+${9:=0}))" || false
}
답변
shift
운영자를 살펴보십시오 . 인수 2를 무시하고 인수 1을 버리고 위치 1 이상으로 이동합니다.
sum () {
local total=0;
while [ $# -gt 0 ]; do
total=$(($total + $1))
shift
done
echo $total
}
답변
sum
인수없이 호출 될 때 종료되는 재귀 정의를 사용할 수 있습니다 . 우리는 test
인수없이 평가 한다는 사실을 이용 합니다 false
.
sum () {
test $1 && echo $(( $1 + $(shift; sum $@) )) || echo 0
}
답변
이 시도:
SUM () {
[ $# -lt "2" ] && return 1
for par in $@; do
local sum=`expr $sum + $par`
done
echo $sum
return 0
}
SUM 3 4 5
SUM 3 4 5 1 1 1 1 2 3 4 5
12와 30이 출력됩니다.
$@
매개 변수를 참조하고 매개 변수 $#
수 (이 경우 3 또는 11)를 리턴합니다.
리눅스 redhat 4에서 테스트
답변
작은 루프를 사용할 수 있습니다.
sum(){
t=0;
for i in "$@"; do t=$((t + i )); done
echo $t;
}
개인적으로, 나는 그냥 perl
또는 awk
대신 사용 합니다.
sum(){
echo "$@" | perl -lane '$s+=$_ for @F; print $s'
}
또는
sum(){
echo "$@" | awk '{for(i=1; i<=NF; i++){k+=$i} print k}'
}
답변
$ 1 ~ $ 9의 기본값으로 0을 사용하십시오.
SUM() {
echo "The sum is $((${1:-0}+${2:-0}+${3:-0}+${4:-0}+${5:-0}+${6:-0}+${7:-0}+${8:-0}+${9:-0}))"
}
보낸 사람 man bash
:
${parameter:-word}
Use Default Values. If parameter is unset or null, the expansion
of word is substituted. Otherwise, the value of parameter is
substituted.
예 :
$ SUM
합계는 0입니다
$ SUM 1 2
합계는 3
$ SUM 1 1 1 1 1 1 1 1 1
합계는 9
awk와 동일한 출력 :
SUM() {
echo -e ${@/%/\\n} | awk '{s+=$1} END {print "The sum is " s}'
}
답변
그것은 내가 시도하고 찾은 내 자신의 솔루션이기도합니다.
SUM() {
echo "The sum is $(($1+$2+$[$3]+$[$4]+$[$5]+$[$6]+$[$7]+$[$8]+$[$9]))"
}
$ SUM 4 6 5
The sum is 15
그러나 @muru의 대답 은 좋습니다.