Kısa cevap: kullanın"$@"
(çift tırnak işaretleyin). Diğer formlar çok nadiren kullanışlıdır.
"$@"
oldukça garip bir sözdizimi. Ayrı alanlar olarak tüm konumsal parametrelerle değiştirilir. Konumsal parametre yoksa ( $#
0'dır), o zaman "$@"
hiçbir şeye genişlemez (boş bir dize değil, ancak 0 öğeli bir liste), eğer bir konumsal parametre varsa o "$@"
zaman eşdeğerdir "$1"
, eğer iki konumsal parametre varsa "$@"
eşdeğerdir "$1" "$2"
, vb.
"$@"
Bir betiğin veya işlevin argümanlarını başka bir komuta aktarmanıza olanak tanır. Sarf malzemesinin çağrıldığı aynı argüman ve seçeneklerle bir komut çağırmadan önce ortam değişkenlerini ayarlama, veri dosyalarını hazırlama vb. İşlemleri yapan sarmalayıcılar için çok kullanışlıdır.
Örneğin, aşağıdaki işlev çıktısını filtreler cvs -nq update
. Dışında çıkış filtreleme ve dönüş statüsünden (olduğu bu grep
yerine daha cvs
), çağırarak cvssm
bazı argümanlar çağıran gibi davranır cvs -nq update
bu argümanlarla.
cvssm () { cvs -nq update "$@" | egrep -v '^[?A]'; }
"$@"
Konumsal parametreler listesine genişler. Dizileri destekleyen kabuklarda, dizinin öğelerinin listesine genişletmek için benzer bir sözdizimi vardır: "${array[@]}"
(ayraçlar zsh dışında zorunludur). Yine, çift tırnaklar biraz yanıltıcıdır: alanların bölünmesine ve dizi elemanlarının desen oluşumuna karşı korurlar, ancak her bir dizi elemanı kendi alanında sona erer.
Bazı eski kabukları tartışmasız bir hataya sahipti: konumsal argümanlar olmadığında, "$@"
boş bir dize içeren tek bir alana genişletildi, hiçbir alana değil. Bu, geçici çözüm${1+"$@"}
yol açtı ( Perl belgeleriyle ünlü oldu ). Bourne kabuğunun ve OSF1 uygulamasının yalnızca eski sürümleri etkilenir, modern uyumlu değiştirmelerinin hiçbiri (kül, ksh, bash,…) etkilenmez. /bin/sh
Bildiğim 21. yüzyılda piyasaya sürülen herhangi bir sistemden etkilenmiyor (Tru64 bakım sürümünü saymazsanız ve hatta /usr/xpg4/bin/sh
güvenli bile olsa , yalnızca #!/bin/sh
komut dosyası etkilenir, #!/usr/bin/env sh
PATH'niz POSIX uyumluluğu için ayarlanmış olduğu sürece komut dosyaları değil ) . Kısacası, bu endişelenmenize gerek olmayan tarihi bir anekdottur.
"$*"
her zaman bir kelimeye genişler. Bu sözcük, aradaki boşlukla birleştirilen konumsal parametreleri içerir. (Daha genel olarak, ayırıcı IFS
değişkenin değerinin ilk karakteridir . Değeri IFS
boş dize ise, ayırıcı boş dizedir.) Konumsal parametreler "$*"
yoksa boş dize, eğer iki varsa konumsal parametreler ve IFS
varsayılan değeri var sonra "$*"
eşdeğer "$1 $2"
, vb.
$@
ve $*
dış tırnaklar eşdeğerdir. Konumsal parametreler listesine, ayrı alanlar gibi genişlerler "$@"
; ancak sonuçta ortaya çıkan her alan, daha önce belirtilmeyen değişken genişlemelerinde olduğu gibi, dosya adı joker karakterleri olarak işlenen ayrı alanlara bölünür.
Örneğin, geçerli dizin üç dosya içeriyorsa bar
, baz
ve foo
daha sonra,:
set -- # no positional parameters
for x in "$@"; do echo "$x"; done # prints nothing
for x in "$*"; do echo "$x"; done # prints 1 empty line
for x in $*; do echo "$x"; done # prints nothing
set -- "b* c*" "qux"
echo "$@" # prints `b* c* qux`
echo "$*" # prints `b* c* qux`
echo $* # prints `bar baz c* qux`
for x in "$@"; do echo "$x"; done # prints 2 lines: `b* c*` and `qux`
for x in "$*"; do echo "$x"; done # prints 1 lines: `b* c* qux`
for x in $*; do echo "$x"; done # prints 4 lines: `bar`, `baz`, `c*` and `qux`