Find komutunda '{}' ve {} arasındaki fark nedir?


18

Gelen belgeler , Ben kullanım her iki yönde bkz:

find . -type f -exec file '{}' \;

find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \

4
Tabii ki, find, komut ile ilgisi yok ve bunun yerine çağrılan komut için uygun alıntı ile ilgisi var gibi görünüyor.
Zoredache

1
Bunu bash yerine balıkla deneyin.
Charles Duffy

Yanıtlar:


24

İçin bashkabuk '{}'ve {}değiştirilebilir. Bütün mermilerde (mesela fish) durum böyle değildir .

Argümanı tek tırnak içine almak, süslü parantezlerin gönderilmesi gerektiğini açıkça belirtir find. Kullanıma bağlı olarak, bash kabuğu bazen kıvırcık parantezlerin yerini alır.

Aşağıda görüldüğü gibi, bash boş parantez yerine geçmez ve komuta geçer. İçin findkomuta, hiç önemli değil.

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

$ echo '{1,3}'
{1,3}

4
Bash ile önemli değil. Balık ile önemli.
Charles Duffy

1
Ben değiştirecekti " are interchangeable"ile " are interchangeable in some shells, not in all of them. ALWAYS use the single quotes to make sure they get passed as-is to the find command"(sen hep (olsalar bile doğru şekilde kullanabilirsiniz sağlayarak iyi alışkanlıkları başlar) belirsiz birini sağlayan bir sistem üzerinde olmak?)
Olivier Dulac

9

Neredeyse tüm kabuk yorumlayıcıları ile '{}'ve arasında kesinlikle bir fark yoktur {}.

Tek tırnaklar normalde gömülü dizeyi başka bir şeyle değiştirilmekten korumak için kullanılır, örneğin:

  • 'a b' iki tek karakter parametresi olacak tırnak işaretleri olmadan tek bir üç karakter parametresidir
  • '$b' kelimenin tam anlamıyla dolar işareti ve onu takip eden b harfi, b değişkeni ne olursa olsun ve muhtemelen ayarlanmamışsa hiçbir şey olmaz
  • '!!' alıntısız iken bazı ünlem işaretleridir ve bazı etkileşimli kabuklarla, tarihe konulan son komuta kadar genişlerler
  • '*' değişmeyen bir yıldız işaretidir, tırnaksız olarak geçerli dizindeki gizli olmayan dosya adları listesiyle değiştirilir.

POSIX standardı ne de ana akım kabukları ne gibi ( sh(Bourne), ksh, bash, ash, dash, zsh, csh, tcsh) genişletmek {}başka bir şeye, tırnak gerekli değildir.

Bununla birlikte, boş bir dize olarak fishgenişleyen egzotik bir kabuk vardır {}, örneğin:

> ps -p %self
  PID TTY          TIME CMD
 5247 pts/1    00:00:00 fish
> echo a {} b '{}'
a  b {}

Muhtemelen GNU findbelgelerinin {}tırnak işaretleri veya ters eğik çizgilerle yoruma karşı korunmayı önermesinin nedeni budur .


9

Çoğu kullanıcı için (özellikle POSIX kabukları kullananlar), hiçbir fark yoktur.

GNU kılavuz sayfasının Örnek bölümüne göre find:

Parantezlerin kabuk komut dosyası noktalama işareti olarak yorumlanmasını önlemek için tek tırnak işaretleri içine alındığına dikkat edin.

Bence GNU man sayfasının yazar (lar) ı dikkatle yanıyor ama ben man sayfalarındaki tüm örneklerin kaşlı ayraçlar vermediğine dikkat ediyorum. Resmi GNU'dan elde edilen bu örnekler, alıntıyı da atlamaktadır.

In POSIX / Tek UNIX Şartname örneklerle parantez edilir alıntı değil kullanıldığında -execseçeneği.

POSIX kabuğunda, parametre genişletme yalnızca parantez içine alınmış özel parametreler olduğunda gerçekleşir, ancak boş parantez içinde gerçekleşmez .

Bash kabuğu, (taşınabilir olmayan) bir özellik olarak küme ayracı genişlemesi içerir , ancak bu tür desenler yalnızca parantez içine virgül veya nokta eklendiğinde genişletilir . Bash ayrıca için parantez kullanan komut gruplama , ama aslında orada sürece bu oluşmaz olan ayracı içindeki komutların bir grup.

Son olarak, çalışan çalıştı find -exec ls -l {} \;yılında sh, dashve tcshancak bu kabukların hiçbiri genişletilmiş {}başka bir şey haline. Diğerlerinin de belirttiği gibi, fishkabuk {}özel davranır , ancak bu bir POSIX kabuğu değildir (yaratıcıları ve kullanıcıları bir avantaj olarak kabul edilir). Bu diş telleri alıntı hiçbir zararı yok bunları atlayarak hakkında suçluluk duymamalısın balık kabuğunu kullanmayın ama tembel typists.


onlar yanlış değil, insanların doğru yolu kullandıklarından emin olmak için çalışıyorlar (yani '{}'yerine kullanın {}), böylece kabukları {}yorumlamadan find komutuna gönderir (eğer balık kullanırsanız, @ Charles-Duffy tarafından belirtildiği gibi) bu yorumlayacaktır {}ama '{}'o kabuk üzerinde ikinci kullanmak gerekir, böylece nedenle, her zaman kullanmak (ve diğerlerini etkisiz!). '{}'belirsizlik tarafından ısırılan önlemek için{}
Olivier Dulac

6

Bu, kabuğunuzun sözdizimine bağlıdır. Şüphe duyduğunuzda yankılanın!

Bunu çalıştır

echo '{}'

ve bu.

echo {}

Aynı çıktıyı üretirlerse, kabuğunuzun cevabı evettir. Diğerlerinin de belirttiği gibi, en azından bashta evet ve balıkta hayır olacaktır. Çıktı, belirli bir komutun kılavuzuna bakmanız gereken şeydir.


Kullanışlı olmak istiyorsanız, kablonuzun gerçekten çağıracağı tüm argümanlarıyla birlikte gerçek komutu echogörmek için tüm komut satırına önek ekleyebilirsiniz . Ancak, komut artı argümanlarını içeren listenin, her biri muhtemelen boş veya boşluklu gerçek bir dizgi dizisi olduğunu, ancak yankıyı boşlukla ayrılmış bir liste olarak belirsiz bir şekilde yazdırdığını unutmayın.

Bu biraz daha ayrıntılı yankı komutuyla doğrulanabileceği gibi (guillemet tarafından alıntılanan argümanları gösterir),

#!/bin/sh
for a in "$@"; do
    printf '«%s» ' "$a"
done
echo ''

bunu komut satırına yazarak,

find 'My Documents and Settings' -type f -exec file {} \;

bash için şu anlama gelir:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»

ve bu balıklarda:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»

Genel bir tavsiye olarak, alıntı yapmak asla acıtmaz.

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.