$ (Stuff) ve `stuff` arasındaki fark nedir?


265

Komutun ikame edilmesinde iki sözdizimi vardır: dolar-parantez ve geri tepme ile. Çalışan top -p $(pidof init)ve top -p `pidof init`aynı çıktıyı verir. Bu iki şeyi aynı şeyi mi yapıyorsunuz, yoksa farklılıklar var mı?


18
Ayrıca bakınız: BashFAQ / 082 .
Dennis Williamson,

42
Bir an için bunun bir jQuery sorusu olduğunu düşündüm.
David Murdoch

Sonuç, kabuğa bağlı olabilir - bazıları her ikisini de destekler.
artdanil

Yanıtlar:


359

Eski stil backquotes ` `ters eğik çizgi ve iç içe biraz farklı davranır. Yeni tarz $(), aralarındaki her şeyi ( )komut olarak yorumluyor .

echo $(uname | $(echo cat))
Linux

echo `uname | `echo cat``
bash: command substitution: line 2: syntax error: unexpected end of file
echo cat

iç içe geçmiş alıntılar kaçarsa çalışır:

echo `uname | \`echo cat\``
Linux

ters eğik çizgi eğlenceli:

echo $(echo '\\')
\\

echo `echo '\\'`
\

Yeni stil $()tüm POSIX uyumlu kabukları için geçerlidir . Mouviciel'in işaret ettiği
gibi , eski kabukları için eski tarz gerekli olabilir.` `

Teknik bakış açısının yanı sıra eski tarzın ` `görsel bir dezavantajı vardır:

  • Fark etmesi zor: I like $(program) better than `program`
  • Tek bir teklifle kolayca karıştırılır: '`'`''`''`'`''`'
  • Yazması o kadar kolay değil (klavyenin standart düzeninde bile olmayabilir)

(ve SE, ` `kendi amaçları için kullanır , bu cevabı yazan bir acıydı :)


10
Ekleyeceğim tek şey, '(' bir paren, braket değil ('' 'dir.).
Kendall Helmstetter Gelner

@Kendall: ve burada düşündüm ki '{' tüm bu yıllar boyunca sol parantez ...
SamB

5
@Sam: { }genellikle "küme parantezi" veya "parantez" olarak adlandırılır en.wikipedia.org/wiki/Braces_(punctuation)#Braces
Jørn Schou-Rode

2
Ayrıca '{' kümesini ayraçlar olarak da adlandırıyorum. Garip görünüyor olsa da, diğer şeyleri parantez olarak adlandırırsanız "kıvırcık" niteleyicisini eklemeniz gerekir ... Sanırım sadece kıvrılmaları nedeniyle.
Kendall Helmstetter Gelner,

1
@slim ABD / İngiltere klavyelerinde bilmiyorum, ancak ispanyolca klavyelerde `ölü bir anahtardır, bu yüzden bir çift-geri dönüş (genellikle yapabileceğimi unutacağım bir şey) veya o zamanki boşluktan sonra yazmam gerekir. Ağrı.
Darkhogg

41

Benim gözlemlediğim bariz fark, yuva kurarken arka ayakları yuvalayamayacağınız $(). Belki her ikisi de eski nedenlerden dolayı var. Benzer şekilde, .ve sourcekomutları eş anlamlıdır.


10
Bazı Bourne türetilmiş kabukları tanımaz source. Dash bir örnek.
Dennis Williamson

14
Bu doğru değil. Geriye doğru tek dokunuşla, daha acı verici bir şekilde yuva yapabilirsiniz. Her iki unutmayın $(...)ve `...`(ikincisi kullanımdan kaldırılma) ise standart .standarttır ancaksource
Stéphane Chazelas

3
Düzeltme, sadece (t)cshiç içe geçemezler. Yine (t)cshde desteklemeyin $(...). Yine de destekliyorlar source(değil .).
Stéphane Chazelas

28

$()eski Bourne kabuğu ile çalışmaz. Ama olmuştur yıllar eski Bourne kabuğu ile çalıştı beri onlarca yıl.


1970'lerde ve 1980'lerin başında olduğu gibi eski, doğru mu?
Christopher

6

Başka bir not, $()backticks kullanmaktan daha fazla sistem kaynağı kullanacak, ancak biraz daha hızlı olacaktır.

In Mastering Unix kabuk komut dosyası Randal K. Michael "Dosya Hattı-Line tarafından Süreç 24 Yolları" adlı bir bölümde bir test yapmıştı.


2
Bu iddia saçmalık. Ayrıştırıcı için yalnızca farklı bir gösterim kullandığı için daha hızlı olması için hiçbir neden yoktur.
schily

@schily: Belki, sadece kitaptan alıntı yapıyorum, daha fazla ayrıntı için okuyabilirsiniz.
cuonglm

3
@Schily ile aynı fikirdeyim ... neden daha fazla kaynak kullandı?
Wildcard

2
@Wildcard, sanırım $()betiğinizin bir byte'ı kullanıldığından daha büyük olmasını sağlıyor `(iç içe geçmediğinizi ve içinde ters eğik çizgi kullanmadığınız varsayılarak). Ayrıştırılması daha hızlı olacağı için, kabuklar arasında değişecektir ve bir boru yaratma maliyetinin ve komutun ikame edilmesinin gerektirdiği sürecin çatallanmasının maliyetine kıyasla ihmal edilebilir derecede önemsiz olacaktır.
Stéphane Chazelas

5

Burada başkalarının söylediklerini eklemek için satır içi yorumları simüle etmek için geri direkleri kullanabilirsiniz:

echo foo `# I'm a comment!` bar

Çıktısı: foo bar.

Daha fazla bilgi için aşağıdakilere bakın: https://stackoverflow.com/a/12797512 (Bu yazının altındaki yorumları da not edin .)


1

$()Sözdizimi eski Bourne kabuğu ile çalışmayacak.
Yeni kabukları ile ` `ve $()eşdeğerdir ancak $()sen yuva birden komutları gerektiğinde kullanmak çok daha uygundur.

Örneğin :

echo $(basename $(dirname $(dirname /var/adm/sw/save )))

yazmak ve hata ayıklamak daha kolaydır:

echo `basename \`dirname \\\`dirname /var/adm/sw/save \\\`\``

1
$ () Güzel gözükse de, ilgili bir ayrıştırıcı uygularken bir acı olur çünkü ikili özyinelemeli ayrıştırıcı gerektirir.
schily

6
@schily Diğer tarafta, iyi bir ayrıştırıcı olmadan bir kabuk ne olurdu.
Emmanuel

1
Sorun, ayrıştırıcıyı çağırmadan önce dizenin nerede bittiğini bilmenizdir. Bu, geri tepmeler ile nispeten basittir, ancak kabukta çeşitli amaçlar için kullanıldığı için braketlerle zordur. Bu nedenle ayrıştırıcıya iki kez ve Bourne Kabuğu'nda olmayan bir şekilde ihtiyacınız var.
schily
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.