Bash ters vuruşları nasıl düzgün şekilde yerleştirilir


95

Ya bazı geri tepmeleri kaçırdım ya da geri tepme çok fazla programcı alıntı döngüsü ile işe yaramıyor gibi görünüyor.

$ echo "hello1-`echo hello2-\`echo hello3-\`echo hello4\`\``"

hello1-hello2-hello3-echo hello4

Aranan

hello1-hello2-hello3-hello4-hello5-hello6-...

Soru muhtemelen "Bash ters vuruşlarını yinelemeli olarak nasıl kullanılır" şeklinde olmalıdır. Bu, Google çalışanlarına yardımcı olacaktır.
Joey Adams

ne yapmaya çalışıyorsun? bunun hiçbir anlamı yok.
ghostdog74

1
@joey, başlık değişti, hoş geldiniz: D
Stormenet

1
Oops, çiz şunu. "Bash'ta zıplamaları nasıl iç içe geçirebilirim?" . Özyineleme ve iç içe geçme karışık.
Joey Adams

Backticks deprecated, bu nedenle kullanın $(cmd).
Timo

Yanıtlar:


149

$(commands)Bunun yerine kullanın :

$ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
hello1-hello2-hello3-hello4

$(commands) ters vuruşlarla aynı şeyi yapar, ancak onları iç içe yerleştirebilirsiniz.

Bash aralığı genişletmeleriyle de ilgilenebilirsiniz:

echo hello{1..10}
hello1 hello2 hello3 hello4 hello5 hello6 hello7 hello8 hello9 hello10

{1..10} gibi +1. Dizi ile sınırlandırılsın mı? ZSH "$ {$ (tarih) [2,4]}" yapabilir. Neden olmasın: "echo $ {echo hello1 - $ (echo hello2) [1]}"?
hhh

35

Ters tikleri kullanmakta ısrar ederseniz, aşağıdakiler yapılabilir

$ echo "hello1-`echo hello2-\`echo hello3-\\\`echo hello4\\\`\``"

Ters eğik çizgi koymanız gerekir, \\ \\\\ \\\\\\\\2x ve benzeri, $(commands)diğerinin önerildiği gibi kullanımı çok çirkin .


11

Bir komutu değerlendirmek istediğinizde şunu kullanın command substitution:

$(command)

Bir aritmetik ifadeyi değerlendirmek istediğinizde şunları kullanın expression substitution:

$((expr))

Bunları şu şekilde iç içe geçirebilirsiniz:

Diyelim ki file1.txt 30 satır uzunluğunda ve file2.txt 10 satır uzunluğunda, şöyle bir ifadeyi değerlendirebilirsiniz:

$(( $(wc -l file1.txt) - $(wc -l file2.txt) ))

20 çıktı (iki dosya arasındaki satır sayısındaki fark).


10

Bash'in iç içe yerleştirilmekten çok daha kolay olan $(cmd) komut ikame sözdizimini kullanırsanız çok daha kolaydır :

$ echo "hello1-$(echo hello2-$(echo hello3-$(echo hello4)))"
hello1-hello2-hello3-hello4

5
Bu, bash ile sınırlı değildir . POSIX 1003.1'e (“POSIX mermiler”) ve Bourne'dan türetilmiş çoğu mermiye ( ksh , kül , tire , bash , zsh , vb.) Uyan tüm mermilerde mevcuttur, ancak gerçek Bourne kabuğu (ör. Heirloom.sourceforge.net) /sh.html ).
Chris Johnsen

vay, bu cevabın zaman damgası @joey_adams cevabındaki KİMLİKTİR! Eşzamanlılık en gerçek anlamıyla :) Burada da oy kullanılıyor (:
drevicko

0

Bazen geri tepme yuvalama yerine xargsve borularla değiştirilebilir

$ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1
hello1 hello2 hello3 hello4

Bu çözümün dezavantajı:

  • Tüm argümanlar ters sırada sağlanmalıdır (4 → 1);
  • Tüm argümanlar boşlukla ayrılır (çözülebilir tr):

    $ echo hello4 | xargs echo hello3 | xargs echo hello2 | xargs echo hello1 | tr ' ' '-'
    hello1-hello2-hello3-hello4
    


Gerçek bir kullanım durumu gösterelim.

Aşağıdaki komutlar bash'de çalışır, ancak tcsh'de çalışmaz (backtick yuvalama tcsh'de çok iyi işlenmez)

$ ls $(dirname $(which bash))
$ ls `dirname \`which bash\``

İle ikame edilebilirler

$ which bash | xargs dirname | xargs ls
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.