* Kabuklarındaki geri tepmeler (yani, cmd `ler) kullanımdan kaldırıldı mı?


118

Bu yorumu Unix ve Linux'ta ve Bash & Zsh gibi mermilerde "backticks itiraz edildi" ifadesini kullanan diğer sitelerde gördüm.

Bu ifade doğru mudur, yanlış mıdır?


Bkz. Neden bir kabuk betiğindeki alıntıları geri yazmadıysam,cd$(...) gösterimin neden iç içe geçmiş alıntılardan daha kolay kullanıldığına ilişkin bir örnek için bir dizine yardımcı olmama bakın .
Jonathan Leffler


1
En az bir Unix, AIX, geri tepmelerin eski olduğunu belgelemiştir . “Ters sözdizimi ksh tarafından kabul edilmesine rağmen, X / Açık Taşınabilirlik Kılavuzu Sayı 4 ve POSIX standartları tarafından eski kabul edilir. Bu standartlar, taşınabilir uygulamaların $ (komut) sözdizimini kullanmalarını önerir.” ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.osdevice/…
Christopher

Ben mac 10.10 tarihinde "GNU bash, versiyon 3.2.57 (1) -salınımı (x86_64-elma-darwin14)" kesin bir fark vardır: matchingLines=$( grep -n '\$-PARAMETER' ... | ... )eserler, matchingLines= backtick the same stuff backtickçalışmıyor - ters eğik çizgi-dolar ters eğik çizgi kaybetmek gibi görünüyor. (Benim senaryom değil ...)
denis,

Yanıtlar:


126

"Kaldırılmış" olmak üzere iki farklı anlam vardır.

kullanımdan kaldırılabilir: (temel olarak bir yazılım özelliğine sahip) kullanılabilir, ancak genellikle geçersiz kılındığından dolayı eski ve en iyi şekilde kaçınılmalıdır.

—Yeni Oxford Amerikan Sözlüğü

Bu tanıma göre backticks edilir kullanımdan kaldırıldı.

Kullanımdan kaldırılan durum, özelliğin gelecekte kaldırılacağını da gösterebilir.

- Wikipedia

Bu tanım gereği, backticks itiraz edilmemektedir .

Hala destekleniyor:

Kabuk Komutanlığı Dillerinde Açık Grup Spesifikasyonundan , özellikle de "2.6.3 Komuta Değiştirme" bölümünden bahseden, her iki komuta ikame formunun, backtick'lerin ( `..cmd..`) veya dolar parensinin ( $(..cmd..)), şartnamenin devam ettiği sürece desteklendiği görülebilir .

alıntı

Komut değiştirme, bir komutun çıktısının, komut adının yerine yerine kullanılmasına izin verir. Komut şu şekilde eklendiğinde, komut değiştirme yapılır:

          $(command)

          or (backquoted version):

          `command`

Kabuk, bir alt kabuk ortamında (bkz. Shell Yürütme Ortamı) komutu yürüterek $()ve bir veya daha fazla sekansı kaldırarak komutun yerine koyma komutunu değiştirerek (komutun metni artı ek veya geri tırnaklar) komutun yerine geçmesiyle komut değiştirme işlemini genişletmelidir. Değişimin sonunda <newline> karakterleri. Çıktının sonundan önce gömülü <newline> karakterleri kaldırılmayacaktır; Bununla birlikte, bunlar IFS'in değerine ve yürürlükte olan alıntılara bağlı olarak saha sınırlayıcıları olarak ele alınabilir ve tarla bölünmesi sırasında elimine edilebilir. Çıktı boş baytlar içeriyorsa, davranış belirtilmemiş.

Tersine çevrilmiş komut değiştirme stilinde, <backslash> , '$', ' \`' veya <backslash> ile belirtilen durumlar haricinde, gerçek anlamını korur . Eşleşen backquote için yapılan arama, ilk alıntılanmamış kaçış olmayan geri alıntı ile sağlanacaktır; Bu arama sırasında, bir kabuk yorumunda çıkmayan $(command)bir geri alıntı ile karşılaşılırsa, burada bir belge, formun gömülü bir komut ikamesi veya alıntı bir dize, tanımlanmamış sonuçlar ortaya çıkar. " `...`" Dizisi içinde başlayan, ancak bitmeyen, tek tırnaklı veya çift tırnaklı bir dize tanımsız sonuçlar üretir.

İle $(command)forma, eşleştirme kapanış parantez açık parantez aşağıdaki tüm karakterler komutunu oluşturmaktadır. Herhangi bir geçerli kabuk betiği, yalnızca belirtilmemiş sonuçları üreten yeniden yönlendirmelerden oluşan bir komut dosyası dışında komut için kullanılabilir.

Öyleyse neden herkes geri tepmelerin kullanımdan kaldırıldığını söylüyor?

Çünkü kullanım durumlarının çoğu , backticks yerine dolar parensinden faydalanıyor olmalı . (Yukarıdaki ilk anlamda kullanımdan kaldırılmıştır.) En saygın sitelerin çoğu (U&L dahil) çoğu zaman bunu da ifade eder, bu yüzden sağlam bir tavsiyedir. Bu tavsiye, geri tepmeler için mermi kovanı desteğini kaldırmak için mevcut olmayan bazı planlarla karıştırılmamalıdır.

  • BashFAQ # 082 - Neden $ (...) `...` (backticks) yerine tercih edilir?

    alıntı

    `...`POSIX uyumlu olmayan bourne mermilerinin yalnızca en eskileri tarafından istenen eski sözdizimidir. $(...)Sözdizimini her zaman tercih etmenin birkaç nedeni vardır :

    ...

  • Bash Hackers Wiki - Eski ve kullanımdan kaldırılan sözdizimi

    alıntı

    Bu, komut yerine koyma işleminin Bourne uyumlu eski şeklidir . Hem `COMMANDS`ve $(COMMANDS)sözdizimi POSIX tarafından belirlenir ancak ikincisi olan büyük ölçüde eski maalesef hala komut çok yaygın olsa tercih. Yeni tarz komut ikameleri her modern kabuk (ve daha sonra bazıları) tarafından yaygın olarak uygulanır. Geri tepme kullanmanın tek nedeni, gerçek bir Bourne kabuğu (Heirloom gibi) ile uyumluluk içindir. Geriye dönme komutunun yerine koymaları, yuvalandıklarında özel olarak kaçmayı gerektirir ve vahşi ortamda bulunan örnekler, alamadıklarından daha sık alıntı yapılır. Bakın: Neden $ (...) `...` (backticks) yerine tercih edilir? .

  • POSIX standart gerekçesi

    alıntı

    Bu tutarsız davranışlardan ötürü, komut değiştirmeleri yerleştiren veya karmaşık komut dosyaları gömme girişiminde bulunan yeni uygulamalar için geri çevrilen komut değiştirme türü önerilmemektedir.

NOT: Bu üçüncü alıntı (yukarıda), backtick'lerin işe yaramayacağı birkaç durum göstermeye devam eder, ancak yeni dolar parensi yöntemi, aşağıdaki paragraftan başlayarak başlar:

Ek olarak, backquoted sözdiziminin gömülü komutun içeriği üzerinde tarihsel kısıtlamaları vardır. Yeni "$ ()" formu her türlü geçerli gömülü betiği işleyebilse de, geri döndürülen form, geri alıntı içeren bazı geçerli komut dosyalarını işleyemez.

Bu bölümü okumaya devam ederseniz, backticks kullanarak nasıl başarısız olacağını gösteren başarısızlıklar vurgulanır, ancak yeni dolar parens notasyonu kullanarak çalışır.

Sonuçlar

Bu nedenle, geri tepme yerine dolar parenini kullanmanız tercih edilir, ancak teknik olarak "kullanımdan tamamen kaldırılmış" olan ve tamamen planlanmış bir noktada çalışmayı durduracak bir şey kullanmıyorsunuzdur.

Tüm bunları okuduktan sonra, özellikle POSIX’li olmayan orijinal bir Bourne kabuğu ile uyumluluk gerektirmedikçe, dolar parenini kullanmaya şiddetle teşvik edilmeniz gerekir.


26
By anlamları çoğu kullanımdan kaldırıldı , ben (ve) backticks söyleyebilirim edilir kullanımdan kaldırıldı. Bu çoğunlukla bir terminoloji sorusudur.
Stéphane Chazelas

4
@StephaneChazelas - Kabul edildi! Ppl'e itiraz edildiklerini söylemeye devam edeceğim ancak backticks'ler yakın bir gelecekte herhangi bir kabuğun kod tabanından aktif olarak çıkarılacakları anlamında resmen “itiraz edilmedi”. En azından hiç bilmediğim.
slm

3
Benim yorumum, backquote'lerin yalnızca desteklenmeyeceği için var olan kodda yerleşik oldukları için tamamen desteklenmesidir. Onları yeni kodda kullanmaya devam ettiğime dair bir tartışma duymadım.
chepner

3
@slm Evet, sanırım aldınız - ben uzaklaştım ve farketmedim. Bunları kullanmak için neredeyse hiçbir neden yoktur, ancak alt kabukların döşenmesi $( cmd `cmd`)sadece biraz daha temiz olabilir, bu yüzden $( cmd $(cmd))okumaktan biraz daha az dağınık olabilir . Yazılımdaki her zaman kullanımdan kaldırılmış bir özelliği, yukarı akış tarafından resmi olarak kaldırılmak üzere işaretlenmiş bir özellik olarak düşündüm - ve böyle bir şey hiç duymadım. Umurumda değil - mezara sevgim yok.
mikeserv

3
POSIX standart gerekçesinden aşağıdaki alıntıyı eklemek isteyebilirsiniz : Bu tutarsız davranışlar nedeniyle, komut değiştirmeleri yerleştiren veya karmaşık komut dosyaları yerleştirmeyi deneyen yeni uygulamalar için ters çevrilmiş komut değiştirme türü önerilmemektedir. Gerekçe bölümü bilgilendirici ve normatif olmadığı için bu resmi bir itiraz değildir, ancak geri tepme kullanımından kaçınılması gerektiği ileri sürülmektedir.
jw013

15

Onaylanmadı, ancak backticks ( `...`) yalnızca POSIX uyumlu olmayan bourne mermilerinin en eskileri için gerekli olan eski sözdizimidir ve $(...)POSIX'tir ve birkaç nedenden dolayı daha çok tercih edilir:

  • Ters eğik \çizgiler ( ), geri tepme izlerinin içindeki açık olmayan bir şekilde ele alınır:

    $ echo "`echo \\a`" "$(echo \\a)"
    a \a
    $ echo "`echo \\\\a`" "$(echo \\\\a)"
    \a \\a
    # Note that this is true for *single quotes* too!
    $ foo=`echo '\\'`; bar=$(echo '\\'); echo "foo is $foo, bar is $bar" 
    foo is \, bar is \\
  • İç içe geçmiş alıntılar $()çok daha uygundur:

    echo "x is $(sed ... <<<"$y")"

    onun yerine:

    echo "x is `sed ... <<<\"$y\"`"

    veya şöyle bir şey yazıyor:

    IPs_inna_string=`awk "/\`cat /etc/myname\`/"'{print $1}' /etc/hosts`

    çünkü $()alıntı için tamamen yeni bir bağlam kullanıyor

    Bourne ve Korn mermileri gibi portatif olmayanlar bu ters eğik çizgilere ihtiyaç duyarken, Bash ve çizgi gerektirmez.

  • İç içe geçme komutu değişimleri için sözdizimi daha kolaydır:

    x=$(grep "$(dirname "$path")" file)

    daha:

    x=`grep "\`dirname \"$path\"\`" file`

    çünkü $()alıntı için tamamen yeni bir bağlam uygular, bu nedenle her bir komut yerine koyma işlemi alıntı yapma ve kaçma konusunda özel bir endişe duymadan korunur ve tek başına ele alınabilir. Geri tepme çubuklarını kullanırken, iki ve daha üst seviyelerin ardından daha çirkin ve çirkinleşir.

    Birkaç örnek daha var:

    echo `echo `ls``      # INCORRECT
    echo `echo \`ls\``    # CORRECT
    echo $(echo $(ls))    # CORRECT
  • Ters alıntılar kullanılırken tutarsız davranış sorununu çözer:

    • echo '\$x' çıktılar \$x
    • echo `echo '\$x'` çıktılar $x
    • echo $(echo '\$x') çıktılar \$x
  • Backticks sözdiziminin gömülü komutun içeriğinde tarihsel kısıtlamalar vardır ve yeni $()form her türlü geçerli gömülü betiği işleyebiliyorken, geri dönüşler içeren bazı geçerli komut dosyalarını işleyemez .

    Örneğin, aksi takdirde bu geçerli gömülü komut dosyaları sol sütunda çalışmaz, ancak sağ IEEE'de çalışır :

    echo `                         echo $(
    cat <<\eof                     cat <<\eof
    a here-doc with `              a here-doc with )
    eof                            eof
    `                              )
    
    
    echo `                         echo $(
    echo abc # a comment with `    echo abc # a comment with )
    `                              )
    
    
    echo `                         echo $(
    echo '`'                       echo ')'
    `                              )

Bu nedenle, $önceden tanımlanmış komut değiştirme için sözdizimi tercih edilen yöntem olmalıdır, çünkü temiz sözdizimi ile görsel olarak açıktır (insan ve makine okunabilirliğini arttırır), nesnel ve sezgiseldir, iç ayrıştırması ayrıdır ve ayrıca daha tutarlıdır ( geri dönüşlerin tek istisna olduğu ve `karakterin kolayca "okunabildiği, özellikle küçük veya sıra dışı yazı tipleri ile komşu olduğunda, çift ​​tırnak içinde ayrıştırılan diğer tüm açılımların) .

Kaynak: Neden $(...)tercih edilir `...`(backticks)? BashFAQ şirketinde

Ayrıca bakınız:

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.