Bir kabuk betiğinde $ @ ne anlama geliyor?


Yanıtlar:


243

$@olan tüm komut geçirilen parametrelerin.

Örneğin, çağırırsanız ./someScript.sh foo baro $@zaman eşit olacaktır foo bar.

Yaparsan:

./someScript.sh foo bar

ve sonra iç someScript.shreferans:

umbrella_corp_options "$@"

bu, umbrella_corp_optionsher bir parametrenin çift tırnak içine alındığı şekilde, arayanın boş alana sahip parametrelerin alınmasına ve aktarılmasına izin verecek şekilde iletilecektir .


1
Yapsaydım $ @ ne içerirdi someScript.sh foo bar "boo far"?
trusktr


7
$ @ çift tırnak ile yazıldığında özeldir. Daha sonra, durumunuzda, trusktr, "foo", "bar" ve "boo far" üç argümanında belirtilen değerlerin bir listesi ile sonuçlanacaktır.
Alfe

4
Genellikle durum olmasına rağmen, $@yok olması gerekmez senaryo ... mesela geçirilen Paramaters gelen; set a b "x   y"; printf '(%s)' "$@"çıkışlar(a)(b)(x   y)
Peter.O

1
$@$*
Alfe'nin

107

$@$*her ikisi de "tüm komut satırı bağımsız değişkenleri" anlamına gelen neredeyse aynıdır . Genellikle tüm argümanları başka bir programa aktarmak için kullanılırlar (böylece diğer programın etrafında bir sargı oluştururlar).

İki sözdizimi arasındaki fark, içinde boşluklar (örneğin) olan bir argümanınız olduğunda ve $@çift ​​tırnak işareti koyduğunuzda ortaya çıkar :

wrappedProgram "$@"
# ^^^ this is correct and will hand over all arguments in the way
#     we received them, i. e. as several arguments, each of them
#     containing all the spaces and other uglinesses they have.
wrappedProgram "$*"
# ^^^ this will hand over exactly one argument, containing all
#     original arguments, separated by single spaces.
wrappedProgram $*
# ^^^ this will join all arguments by single spaces as well and
#     will then split the string as the shell does on the command
#     line, thus it will split an argument containing spaces into
#     several arguments.

Örnek: Sesli arama

wrapper "one two    three" four five "six seven"

sonuçlanacak:

"$@": wrappedProgram "one two    three" four five "six seven"
"$*": wrappedProgram "one two    three four five six seven"
                             ^^^^ These spaces are part of the first
                                  argument and are not changed.
$*:   wrappedProgram one two three four five six seven

2
Bunlar aynı değildir ve manpage, mutlaka yer olması gerekmeyen IFS kullanarak $ * 'ın yan etkileri konusunda nettir. (Aynı olsaydı, belki de her ikisini de sunan uyumluluk dışında herhangi bir nokta olmazdı.)
jørgensen

6
Hayır değiller. Ve ben aşağıda iki satır söyledim: "İkisi arasındaki fark ..." Kısa cümleler almak ve okunabilirliği artırmak için okuyucunun bir karar vermeden önce birden fazla cümle okuması gerekiyor: - /
Alfe

2
Alfe, Christoffer'ın bu "neredeyse" kelimesini eklemesi, herhangi bir kıvraklık veya okunabilirlikten ödün vermeden bir fark yarattı. Aslında, bu cevabı (kabul edilenin aksine) tam olarak farkın bu ince vurgusundan dolayı destekledim ... - neredeyse isteğinize karşı olduğunu fark etmeden önce! ;)
Sz.

Bu kelimenin ilk cümleyi okuduktan hemen sonra karar veren insanlar için bir fark yarattığını düşünüyorum ;-) ve bu benim irademe asla karşı değildi. Bu insanlar için de gerçekten yazmak istiyorum.
Alfe

Çok net değil. wrappedProgram "$*"-> separated by single spaces.ancak 2. örneğinizde tek boşluklarla ayrılmazlar.
Felix Dombek

36

Bunlar komut satırı bağımsız değişkenleridir:

$@= tüm argümanları string listesinde
$*saklar = tüm argümanları tek bir string olarak
$#saklar = argüman sayısını saklar


(@İruvar tarafından belirtilen yukarıdaki yanlışlık giderildi.)
Mateen Ulhaq

13

Saf kullanımı $@Çoğu durumda araç "programlayıcıyı olabildiğince incitir", çünkü çoğu durumda kelime ayırma ve bağımsız değişkenlerdeki boşluklar ve diğer karakterlerle ilgili sorunlara yol açar.

Tüm vakaların% 99'unda, onu içine almak gerekir ": "$@"argümanlar üzerinde güvenilir bir şekilde tekrarlamak için kullanılabilir.

for a in "$@"; do something_with "$a"; done

4
Satırınız şu şekilde yazılabilir: for a; "$ a" ile bir şeyler yapın; bitti ;-)
Alfe

1
@Alfe biliyorum; sadece unutmuşum. Düşünün for a in start_token "$@" end_token; do something_with "$a"; done:-)
glglgl

9

Kılavuzdan:

@

Birinden başlayarak konumsal parametrelere genişler. Genişletme çift tırnak içinde gerçekleştiğinde, her parametre ayrı bir kelimeye genişler. Yani, "$ @", "$ 1" "$ 2" ile eşdeğerdir. Çift tırnaklı genişleme bir sözcük içinde gerçekleşirse, ilk parametrenin genişlemesi orijinal kelimenin başlangıç ​​kısmı ile birleştirilir ve son parametrenin genişletilmesi orijinal sözcüğün son kısmı ile birleştirilir. Hiçbir konum parametresi olmadığında, "$ @" ve $ @ hiçbir şeye genişlemez (yani kaldırılır).


1

Anlam.

Kısacası, $@çağırandan bir işleve veya bir betiğe geçirilen konumsal bağımsız değişkenlere genişler . Anlamı bağlama bağlıdır : Bir işlevin içinde, bu işleve iletilen argümanlara genişler. Bir komut dosyasında kullanılırsa (kapsamın içinde bir işlev değildir), bu komut dosyasına geçirilen bağımsız değişkenlere genişler.

$ cat my-sh
#! /bin/sh
echo "$@"

$ ./my-sh "Hi!"
Hi!
$ put () ( echo "$@" )
$ put "Hi!"
Hi!

Kelime bölme.

Şimdi, $@kabukta nasıl davrandığını anlarken çok önemli olan başka bir konu kelime bölme . Kabuk, IFSdeğişkenin içeriğine göre belirteçleri böler . Varsayılan değeri \t\n; boşluk, sekme ve satırsonu.

Genişletme "$@"size iletilen bağımsız değişkenlerin bozulmamış bir kopyasını verir . Ancak, genişleme $@her zaman olmaz. Daha spesifik olarak, bağımsız değişkenler karakter içeriyorsa IFSbölünürler.


Çoğu zaman kullanmak isteyeceğiniz şey "$@"değil $@.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.