$#
argüman sayısıdır, ancak bir işlevde farklı olacağını unutmayın.
$#
, komut dosyasına geçirilen konumsal parametrelerin sayısı, kabuk, veya kabuk işlevi . Bunun nedeni, bir kabuk işlevi çalışırken, konumsal parametreler geçici olarak argümanlarla değiştirilir. işlevine. Bu, işlevlerin kendi konumsal parametrelerini kabul etmesini ve kullanmasını sağlar.
Bu komut dosyası, komut dosyasının kendisine kaç tane argümanın aktarıldığına bakılmaksızın her zaman 3
yazdırır, çünkü "$#"
işlevindeki f
işlevi, işleve iletilen argümanların sayısına doğru genişler:
#!/bin/sh
f() {
echo "$#"
}
f a b c
Bu önemli çünkü konumsal parametrelerin kabuk işlevlerinde nasıl çalıştığını bilmiyorsanız, böyle bir kodun beklediğiniz gibi çalışmadığı anlamına gelir:
#!/bin/sh
check_args() { # doesn't work!
if [ "$#" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "#!/bin/sh
check_args() { # works -- the caller must pass the number of arguments received
if [ "" -ne 2 ]; then
printf '%s: error: need 2 arguments, got %d\n' "$ ./check-args-demo a b c
./check-args-demo: error: need 2 arguments, got 3
" "" >&2
exit 1
fi
}
# Maybe check some other things...
check_args "$#"
" "$#" >&2
exit 1
fi
}
# Maybe check some other things...
check_args
# Do other stuff...
check_args
, $#
işlevi, kendisine gönderilen argümanların sayısına doğru genişler ve bu betikte her zaman 0 olur.
Bir kabuk işlevinde bu tür bir işlev istiyorsanız, bunun gibi bir şey yazmanız gerekir:
#!/bin/sh
outer() {
inner() {
printf 'inner() got %d arguments\n' "$#"
}
printf 'outer() got %d arguments\n' "$#"
inner x y z
}
printf 'script got %d arguments\n' "$#"
outer p q
Bu, $#
işlevinin dışında işlevi ve konumsal parametrelerinden biri olarak işleve iletilmesi nedeniyle çalışır. İşlev içinde
, parçası olduğu betiğe değil, kabuk işlevine iletilen ilk konumsal parametreye genişler.
Böylece, $#
gibi,
,
vb. gibi özel parametreler, [email protected]
ve $*
gibi parametreler de, bir işleve iletilen argümanlarla ilgilidir. işlev. Bununla birlikte, nested
işlevi işlevinin adına çevirmiyor, bu yüzden hala kaliteli bir hata mesajı üretmek için kullanabildim.
$ ./nested a
script got 1 arguments
outer() got 2 arguments
inner() got 3 arguments
Benzer şekilde, bir işlevi diğerinin içinde tanımlarsanız, genişletmenin gerçekleştirildiği en içteki işleve iletilen konumsal parametrelerle çalışıyorsunuz:
#!/bin/sh
while [ "$#" -ne 0 ]; do
printf '%d argument(s) remaining.\nGot "%s".\n\n' "$#" ""
shift
done
Bu komut dosyasını chmod +x nested
olarak çağırdım ve ( shift
çalıştırdıktan sonra) çalıştırdım:
$ ./do-shift foo bar baz # I named the script do-shift.
3 argument(s) remaining.
Got "foo".
2 argument(s) remaining.
Got "bar".
1 argument(s) remaining.
Got "baz".
Evet, biliyorum. "1 argüman" çoğullama hatasıdır.
Konumsal parametreler de değiştirilebilir.
Bir komut dosyası yazıyorsanız, bir fonksiyonun dışındaki konumsal parametreler, komut satırına değiştirmediğiniz sürece komut satırı argümanları olacaktır .
.
Bunları değiştirmenin yaygın bir yolu,% konum_adı% yerleşkesidir; bu, her bir konumsal parametreyi sola kaydırır, ilkini bırakır ve $#
'yi 1:
azaltır.
#!/bin/sh
printf '%d args: %s\n' "$#" "$*"
set foo bar baz
printf '%d args: %s\n' "$#" "$*"
$ ./set-args a b c d e # I named the script set-args.
5 args: a b c d e
3 args: foo bar baz
Ayrıca, set
builtin ile de değiştirilebilirler:
%pre%
%pre%