Seçim senin. Eğer alıntı yoksa $@
kendi değerlerinden herhangi bir ek genişleme ve yorumunu uğrarlar. Alıntı yaparsanız, iletilen tüm bağımsız değişkenler işlev genişletme kelimesi kelimesinde çoğaltılır. Sen güvenilir gibi kabuk sözdizimi belirteçleri üstesinden asla &>|
vb zaten argümanlar kendiniz ayrıştırma olmadan her iki şekilde - ve ya da fonksiyon birini devretmeyi de daha makul seçenek kalır geriye böylece:
- Tam olarak kullanılan kelimelerle tek bir basit komutun yürütülmesinde
"$@"
.
...veya...
- Yalnızca daha sonra birlikte basit bir komut olarak uygulanan bağımsız değişkenlerin daha genişletilmiş ve yorumlanmış bir sürümü
$@
.
Eğer kasıtlıysa ve seçtiğiniz şeyin etkileri iyi anlaşılmışsa hiçbir şekilde yanlış değildir. Her iki yolun da diğerine göre avantajları vardır, ancak ikincisinin avantajlarının nadiren özellikle yararlı olması muhtemeldir. Hala ...
(run_this(){ $@; }; IFS=@ run_this 'ls@-dl@/tmp')
drwxrwxrwt 22 root root 660 Dec 28 19:58 /tmp
... değil mi yararsız , sadece nadiren muhtemelen çok olması kullanım . Ve bir bash
kabukta, çünkü söz konusu tanım özel bir yerleşimin veya bir işlevin komut satırına eklenmiş olsa bile bash
varsayılan olarak ortamına değişken bir tanım yapıştırmaz , global değeri $IFS
etkilenmez ve bildirimi yereldir sadecerun_this()
çağrı.
Benzer şekilde:
(run_this(){ $@; }; set -f; run_this ls -l \*)
ls: cannot access *: No such file or directory
... globbing de yapılandırılabilir. Alıntılar bir amaca hizmet eder - hiçbir şey için değildir. Bunlar olmadan kabuk genişleme ekstra yorumunu geçmesi - yapılandırılabilir yorumunu. Eskiden - bazı çok ile eski - kabukları $IFS
edildi küresel uygulanan tüm giriş ve sadece açılımları. Aslında, adı geçen mermiler run_this()
, tüm giriş kelimelerini değerinde kırdıkları için olduğu gibi davranıyordu $IFS
. Ne arıyorsanız o çok eski kabuk davranışı ise Ve böylece, o zaman gerektiğini kullanmakrun_this()
.
Onu aramıyorum ve şu anda bunun için yararlı bir örnek bulmak için oldukça zorlandım. Genelde kabuğumun çalıştırdığı komutları yazdığım komutlar olarak tercih ederim. Ve böylece, seçim göz önüne alındığında, neredeyse her zaman olurdu run_that()
. Bunun haricinde...
(run_that(){ "$@"; }; IFS=l run_that 'ls' '-ld' '/tmp')
drwxrwxrwt 22 root root 660 Dec 28 19:58 /tmp
Hemen hemen her şey alıntılanabilir. Komutlar alıntılanır. Komut gerçekten çalıştığında, tüm girdi sözcükleri zaten kabuğun girdi yorumlama işleminin son aşaması olan alıntı kaldırma işleminden geçmiştir. Yani arasındaki fark 'ls'
ve ls
can yalnızca madde kabuk yorumlarken - ve en niçin alıntı olduğunu ls
herhangi olmasını sağlar takma adlı ls
benim alıntılanan yerine edilmez ls
komut kelimesi. Bunun dışında, alıntı yapan tek şey kelimelerin sınırlandırılmasıdır (değişken / girdi-boşluk alıntılarının nasıl ve neden çalıştığıdır) ve metakarakterlerin ve ayrılmış kelimelerin yorumlanmasıdır.
Yani:
'for' f in ...
do :
done
bash: for: command not found
bash: do: unexpected token 'do'
bash: do: unexpected token 'done'
Bunu asla run_this()
veya ile yapamazsınız.run_that()
.
Ancak işlev adları ya da $PATH
'd komutları ya da yerleşikler iyi alıntılanmış ya da sıralanmamış yürütülür ve ilk etapta tam olarak nasıl çalışır run_this()
ve run_that()
çalışır. $<>|&(){}
Bunlardan hiçbiriyle yararlı bir şey yapamazsınız . Kısa eval
, öyle.
(run_that(){ "$@"; }; run_that eval printf '"%s\n"' '"$@"')
eval
printf
"%s\n"
"$@"
Ancak onsuz, kullandığınız alıntılar sayesinde basit bir komutun sınırlarıyla sınırlandırılırsınız (komutlar meta karakterler için ayrıştırıldığında işlemin başında bir teklif gibi davranır çünkü bunu yapmazsanız bile $@
) . Aynı kısıtlama, işlevin komut satırı ile sınırlı olan komut satırı atamaları ve yeniden yönlendirmeleri için de geçerlidir. Ama bu çok önemli değil:
(run_that(){ "$@";}; echo hey | run_that cat)
hey
Kolayca <
yeniden yönlendirilebilen bir giriş ya da>
Boruyu çıkışa .
Her neyse, yuvarlak bir şekilde, burada doğru veya yanlış bir yol yoktur - her yolun kullanımları vardır. Sadece kullanmak istediğiniz gibi yazmanız ve ne yapmak istediğinizi bilmeniz gerekir. Aksi orada olmaz - atlayarak tırnak bir amaç olabilir olmak hiç tırnak - ama amaç alakalı olmayan nedenlerden dolayı onları atlarsanız, sadece kötü kod yazıyoruz. Ne demek istediğini yap; Her neyse deniyorum.
run_that
'nin davranışı kesinlikle beklediğim şeydir (ya komuta giden yolda bir boşluk varsa?). Diğer davranışı isteseydiniz , verinin ne olduğunu bildiğiniz call -site'den kesinlikle vazgeçer misiniz? Bu işlevirun_that ls -l
her iki sürümde de aynı şekilde çalışmasını beklerim. Farklı şekilde beklemenizi sağlayan bir vaka var mı?