{Ayraç genişletmede kullanılabileceğini fark ettim :
echo {1..8}
veya komut gruplarında:
{ls;echo hi}
Bash farkı nereden biliyor?
{ls;echo hi}yasal değildir bash. Açılıştan sonra bir boşluk ve kapanmadan önce bir noktalı virgül gerekir.
{Ayraç genişletmede kullanılabileceğini fark ettim :
echo {1..8}
veya komut gruplarında:
{ls;echo hi}
Bash farkı nereden biliyor?
{ls;echo hi}yasal değildir bash. Açılıştan sonra bir boşluk ve kapanmadan önce bir noktalı virgül gerekir.
Yanıtlar:
Basitleştirilmiş bir nedeni bir karakter varlığıdır: space.
Parantez açılımları (kote olmayan) boşlukları işlemez.
Bir {...}liste (alıntılanmamış) boşluklar gerektirir.
Daha ayrıntılı cevap, kabuğun bir komut satırını nasıl ayrıştırdığıdır .
Bir komut satırını ayrıştırma (anlama) ilk adımı bölümlere ayırmaktır.
Bu bölümler (genellikle kelimeler veya belirteçler olarak adlandırılır) her meta-karakterdeki bir komut satırını linkten ayırmaktan kaynaklanır :
- Komutu, sabit meta-karakter kümesi ile ayrılmış belirteçlere böler: SPACE, TAB, NEWLINE,;, (,), <,>, |, ve &. Simge türleri arasında kelimeler, anahtar kelimeler, G / Ç yönlendiricileri ve noktalı virgül bulunur.
Meta karakterler: spacetabenter;,<>|and &.
Bölünmeden sonra, kelimeler bir tür olabilir (kabuk tarafından anlaşıldığı gibi):
LC=ALL ... LC=ALL echo LC=ALL echo "hello" LC=ALL echo "hello" >&2 Yalnızca bir "ayraç dizesi" (boşluklar veya meta karakterler olmadan) tek bir sözcükse (yukarıda açıklandığı gibi) ve alıntılanmadıysa , "Ayraç genişletme" için bir adaydır. Daha sonra iç yapı üzerinde daha fazla kontrol yapılır.
Böylece, bu: ya da (bash'da zsh farklı) {ls,-l}olmak için "Brace genişlemesi" olarak nitelendirilir .ls -lfirst wordargument
$ {ls,-l} ### executes `ls -l`
$ echo {ls,-l} ### prints `ls -l`
Ama bu olmaz: {ls ,-l}. Bash bölünür spaceve satırı iki kelimeyle ayrıştırır: {lsve ,-l}hangisini tetikleyecektir command not found(bağımsız değişken ,-l}kaybolur):
$ {ls ,-l}
bash: {ls: command not found
Satır: iki meta karakter ve {ls;echo hi}çünkü "Brace genişleme" olmayacak .;space
Bu üç bölüme ayrılacaktır: {lsYeni komutu: echo hi}. ;Yeni bir komutun başladığını tetiklediğini anlayın . Komut {lsbulunmayacak ve bir sonraki komut basılacaktır hi}:
$ {ls;echo hi}
bash: {ls: command not found
hi}
Başka bir komuttan sonra yerleştirilirse, aşağıdakilerden sonra yeni bir komut başlatır ;:
$ echo {ls;echo hi}
{ls
hi}
"Bileşik komutları" biri "Ayraç Listesi" (sözlerim) 'dir: { list; }.
Gördüğünüz gibi boşluk ve kapanışla tanımlanır ;.
Boşluklar ve ;hem çünkü ihtiyaç vardır {ve }"Ayrılmış olan Kelimeler ".
Ve bu nedenle, kelimeler olarak tanınmak için, meta-karakterlerle çevrili olmak gerekir (hemen hemen her zaman:) space.
Bağlantılı sayfanın 2 noktasında açıklandığı gibi
- Her komutun ilk belirteci olup olmadığını kontrol etmek için ...., {, veya () olup olmadığını kontrol eder, sonra komut aslında bir bileşik komuttur.
Örnek: {ls;echo hi}bir liste değil.
Bir kapanma ;ve en az bir kere sonra boşluk gerekir {. Sonuncusu }kapanış tarafından tanımlanır ;.
Bu bir liste { ls;echo hi; }. Ve bu { ls;echo hi;}da (daha az kullanılan, ancak geçerli) (Yardım için teşekkürler @choroba).
$ { ls;echo hi; }
A-list-of-files
hi
Ancak bir komutun argümanı (kabuk farkı bilir), bir hatayı tetikler:
$ echo { ls;echo hi; }
bash: syntax error near unexpected token `}'
Ama kabuğun ayrıştırdığına inandığına dikkat et:
$ echo { ls;echo hi;
{ ls
hi
;ve }. { ls;}noktalı virgül zaten bir meta karakter olduğu için çalışır.
Blok {bir kabuk anahtar sözcüğüdür, bu nedenle bir sonraki kelimeden boşlukla ayrılmalıdır, küme ayracı genişletmede boşluk kalmamalı (boşluk genişletmek gerekirse, kaçmak zorunda kalırsınız:) echo {\ ,a}{b,c}.
Bir komutun başında ayraç genişletme kullanabilirsiniz:
{ls,.} # expands to "ls ."
Gruplandırma komutlarının ayrıştırılması genişletmelerden önce gerçekleştiğinden, bir bloğa genişletmek için kullanamazsınız:
echo {'{ ls','.;}'} # { ls .;}
{'{ ls','.;}'} # bash: { ls: No such file or directory
Komut satırının sözdizimini kontrol ederek bilir. Aynı şekilde, ifadede echo echo, ilk yankının bir komut olarak ve ikinci yankının, ilk yankının bir parametresi olarak ele alınması gerektiğini bilir .
Bash'te çok basittir, çünkü { cmd; }boşluk ve noktalı virgül içermelidir. Bununla birlikte, örneğin, zsh'de gerekli değildir, ancak yine de {}kabuk bağlamı analiz edilerek içeriği ile ne yapılması gerektiğini söyleyebilirsiniz.
Aşağıdakileri göz önünde bulundur:
alias 1..3=date
{ 1..3; } #in bash
{1..3} #in zsh
Her ikisi de geçerli tarihi döndürür, ancak
echo {1..3}
1 2 3shell {}komutunun argümanında olduğunu bildiğinden döner echo, böylece genişletilmelidir.
{ardından tırnaksız boşluk, bash'ta ayraç genişlemesine başlamaz.
{. Tırnaksız alan hiçbir yerde olamaz çünkü kabuk tüm komut satırını boşluklara böler.
Öncelikle, bir bileşik küme teker teker ve komut satırının ilk sözcüğü olmalıdır:
echo { these braces are just words }
İkincisi, bireysel diş telleri özel değildir (yukarıda gördüğünüz gibi). Boş parantezler de özel değildir:
echo {} # just the token {}: familiar from the find command
Virgülsüz herhangi bir şey aynı zamanda sadece kendisidir
echo {abc} # just {abc}
Aksiyonun başladığı yer burasıdır.
echo {a,b} # braces disappear, a b results.
Dolayısıyla, temel olarak küme genişlemesinin başlayabilmesi için, içinde {...}en az bir virgül bulunan en az bir örneği olduğu tek bir kelimeye (beyaz alandaki alanlara ayrılmamış) ihtiyacımız var.
Bu arada, komut satırındaki ilk sözcük olabilir :
{ls,-l} . # just "ls -l ."
{, bir komutun başında ve aksi bir bağ genişleme olarak görünse bile bir komut listesi olarak yorumlanır, ama emin değilim.