GNU bazı kabukları için {} 'yi bulup maskeliyor - hangisi?


34

GNU’nun man sayfası şu durumları bulur:

-exec command ;
    [...] The  string `{}'  is  replaced  by the current 
    file name being processed everywhere it occurs in the 
    arguments to the command, not just in arguments where 
    it is alone, as in some  versions  of  find.
    Both  of  these  constructions might need to be escaped 
    (with a `\') or quoted to protect them from expansion 
    by the shell. 

Bu adamdan find(GNU bulgusuna kadar) 4.4.2.

Şimdi bunu bash ve dash ile test ettim ve her ikisinin {}de maskelenmesine gerek yok . İşte basit bir test:

find /etc -name "hosts" -exec md5sum {} \; 

Diş tellerini maskelemem gereken bir kabuk var mı? Unutmayın, bulunan dosyanın boş (bashtan çağrılmış) içerip içermediğine bağlı değildir

find ~ -maxdepth 1 -type d -name "U*" -exec ls -d {} \; 
/home/stefan/Ubuntu One

Bu, bulunan dosya bir alt kabuğa geçirilirse değişir:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d {}' \; 
ls: cannot access /home/stefan/Ubuntu: No such file or directory
ls: cannot access One: No such file or directory

hangi tarafından çözülebilir:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "$0"' {} \;

kıyasla:

find ~ -maxdepth 3 -type d -name "U*" -exec bash -c 'ls -d "{}"' \; 
/home/stefan/Ubuntu One

ama bu man sayfasının bahsettiği şey değil, değil mi? Peki hangi kabuk {}farklı şekilde davranıyor ?


@Volker Siegel: Düzenlemeniz iyi niyetli olarak yapılmış olabilir, ancak mevcut bulma kılavuzumu kontrol ettim ve düzeltmeleriniz yanlış, Ayrıca kötü bir alışkanlık olan düzenlemelerinizi özetleme fırsatını kaçırdınız, Değişikliklerinizi geri alıyorum. Üzgünüm dostum.
kullanıcı bilinmeyen

Bir şey kırdıysa geri aldığın için teşekkürler. Render tanımının bir eseri olarak bu "tipografik alıntıları" oluşturmak için kullanılan man sayfa formatını oluşturan metin derleyicisinin hatırlıyorum. Ayrıca, mükemmel çıktı formatlama için TeX'e de verebilir. Alıntıları farkettim çünkü sözdizimi vurgulamasını karıştırdılar. Kodda kullanıldığında olağandışı ilk teklifin yanlış olduğunu kabul ettim ve yine de bunu varsaydım. İki değişikliğin kodda değil açıklama metninde bulunduğunu unutmayın. Öyleyse onları tipografi olarak görürsek - estetik sunum - haklılar.
Volker Siegel

Bilgi çıktısı oluşturma işleminde benziyor, aynı alıntı her iki tarafta da kullanılıyor. Hiç şüphem yok, değişikliğim onu ​​orijinalden farklı kıldı, haklısın. Fakat herhangi bir soruna neden oldu mu? (İlk teklifi, render oluşturma tanımındaki bir hata olarak kabul ediyorum, bildiğim kadarıyla tipografinin tek örneği bu.)
Volker Siegel

Ben sadece kontrol ettim: `{} 'komut satırında çalışmıyor. Bu teknik olarak doğru, ama yanlış bir kullanıcının kopyalayıp yapıştırmaya çalıştığında garip bir hata almasından hoşlanmıyorum.
Volker Siegel

@ VolkerSiegel: Kod değil, metin nesirdir, bu yüzden bir kullanıcı buraya kopyala-yapıştır ne yapmalı? Ve bu, man sayfasının 2011'den bir alıntıdır. Geçişi düzelten hiçbir değeri göremiyorum, neden man sayfasına düzeltmeler yaptım? Konu yeterince karmaşık. Bu senin sorunun olsaydı, sizi adam sayfasını doğru bir şekilde alıntılamaya ikna etmeye çalışmam ama benim sorum için uzlaşma yapma havasında değilim. Alıntı, alıntıdır.
kullanıcı bilinmeyen

Yanıtlar:


26

Özet : Genişleyen bir kabuk varsa, şimdiye dek {}gerçekten eski olan şey.

Bourne kabuğunun içinde ve POSIX uyumlu kabuklarında, desteklerin ( {ve }) (farklı sıradan karakterler (ve )gibi kelime sınırlayıcılardır ;ve &ve [ve ]karakter globbing edilir). Aşağıdaki dizgilerin kelimenin tam anlamıyla basılması gerekiyor:

$ echo { } {} {foo,bar} {1..3}
{ } {} {foo,bar} {1..3}

Tek bir ayraçtan oluşan bir sözcük , yalnızca komutun ilk sözcüğü olması durumunda özel olan ayrılmış bir sözcüktür .

Ksh, ayraç genişlemesini Bourne kabuğuna uyumsuz bir uzantı olarak uygular. Bu ile kapatılabilir set +B. Bash bu konuda ksh'ı taklit eder. Zsh, ayrıca ayraç genişletme uygular; orada set +Iveya setopt ignore_bracesveya ile kapatılabilir emulate sh. Bu kabukların hiçbiri, ve ' nin argümanlarındaki ortak kullanımdan dolayı {}bir kelimenin (örneğin foo{}bar) bir alt dili olsa bile, hiçbir şekilde genişlemez .findxargs

Tek Unix v2 notları

Bazı tarihi sistemlerde, küme parantezleri kontrol operatörleri olarak kabul edilir. Gelecekteki standardizasyon aktivitelerine yardımcı olmak için, taşınabilir uygulamalar karakterlerin kendilerini temsil etmek için tırnaklı olmayan teller kullanmaktan kaçınmalıdır. Gelecekte ISO / IEC 9945-2: 1993 standardının bir versiyonunun bunu gerektirmesi {ve }kontrol operatörleri olarak ayrı ayrı ele alınması gerekebilir , ancak belirteç {}sıklıkla kullanılan find {}yapı nedeniyle bunun için özel bir durum muafiyeti olacaktır .

Bu not standardın sonraki sürümlerine bırakılmıştır; için örneklerfind arasında tırnaksız kullanan var {}yapın örneklerxargs . {}Alıntı yapılması gereken tarihi Bourne kabukları olabilirdi, ancak şimdiye kadar gerçekten eski miras sistemleri olacaktı.

El altında Ben csh uygulamaları (OpenBSD 4.7, Debian BSD csh , tcsh) Tüm genişletmek {foo}için fooama bırakın {}yalnız.


1
@geekosaur: Yorumlarda yalnızca küçük bir işaretleme alt kümesi çalışıyor . Ne demeye çalıştığını bilmiyorum. Bu, ksh ve arkadaşlarının küme genişlemesiyle ilgiliyse, “Ksh uyumsuz bir uzatma olarak küme genişlemesini uygular” ile başlayan paragrafımı okuyun.
Gilles 'SO- kötü kalmayı'

2
Bu bash(bkz. $BASH_VERSION) İdi . Brace genişlemesi çok canlı ve iyi.
geekosaur

2
O oldu nokta. {}Sözdizimi kökenli csh, ama {}boş bir dizeye genişletilmiştir. Daha yeni mermiler bunun saçma sapan olduğunu biliyor, ancak hala orada bazı yaşlılar cshvar.
geekosaur

1
@geekosaur: Hangi platformda hangi belirli csh versiyonunu söyleyebilir misiniz? Kendim test etmeyi tercih ederim (eğer Linux'ta mümkün ise) veya emin olun, kişinin kendisi tarafından test edilmesi.
kullanıcı bilinmeyen,

1
@geosaosa, {}foogenişleyecekti fooama {}genişleyecekti {}( geri tepmelerin içindeyken ama alıntı yapmak yardımcı olmuyordu ) ve böyle belgelenmişti. 2BSD (ilk sürüm), 2.79BSD, 2.8BSD ve 2.11BSD'nin csh değerlerini doğruladım.
Stéphane Chazelas,

12

{}Sürümlerinde alıntı gereken fish3.0.0 öncesinde kabuk.

$ fish -c 'echo find -exec {} \;'
find -exec  ;

Ve rc kabuğundaki (ayrıca , ama akangadayalı rcdeğil es):

$ rc -c "echo find -exec {} ';'"
line 1: syntax error near '{'

Bunlar muhtemelen GNU’nun yazarlarının belgelerin fish, 2005’te ilk kez yayınlandığından beri (o metin veya benzerleri 1994’te zaten vardı) ve rcorijinal olarak bir Unix kabuğu olmadıklarını yazdıklarında yazdıklarında buldukları kabukları değillerdir.

Bunu gerektiren bazı sürümlerinin csh(ayraç genişlemesine neden olan kabuk) bazı söylentileri vardır . Ancak csh2BSD’de yayımlanan ilk sürümden bu yana bunlara kredi vermek zor . PDP11 emülatöründe test edildiği gibi:

# echo find -exec {} \;
find -exec {} ;

Ve 2BSD'deki man sayfası cshaçık bir şekilde :

Özel bir durum olarak `{',`}' ve `{} 'rahatsız edilmeden geçilir.

Bu yüzden daha sonra csh veya tcsh bir sonraki sürümü bunu kırdı eğer çok garip bulurdum.

Bazı sürümlerde bazı hataların etrafında çalışmak olabilirdi. Yine de bu 2BSD csh ile (bu 2.79BSD, 2.8BSD, 2.11BSD'de aynıdır):

# csh -x
# echo foo {} bar
echo foo {} bar
foo {} bar
# echo `echo foo {} bar`
echo `echo foo {} bar`
echo foo {} bar
foo  bar

Alıntı yapmak da yardımcı olmuyor:

# echo `echo foo '{}' bar`
echo `echo foo '{}' bar`
echo foo {} bar
foo  bar

Komut değişikliğinin tamamını alıntı yapabilirsiniz:

# echo "`echo foo {} bar`"
echo `echo foo {} bar`
echo foo {} bar
foo {} bar

Ama bu dış yankı için bir argüman geçiyor.

Gelen cshveya tcsh, sen alıntı gerekiyordu {}gibi zaman kendine ait değil:

find . -name '*.txt' -type f -exec cp {} '{}.back' \;

(bu tür bir findkullanım, bazılarının findyalnızca {}kendi başlarına genişlettiğinden taşınabilir olmamasına rağmen ).


1

Bir kelimeyle csh,. bashve diğer modern mermiler, kullanıcının muhtemelen boş bir ayraç genişletmesi istemediğini kabul eder. (Modern csh, aslında tcshve {}şimdiye kadar da aklı başında olabilir .)


Bunu duyduğuma sevindim, ama tam tersi için soruyorum, bunun için mantıklı olmayan bir kabuk.
kullanıcı bilinmeyen,

Linux sistemlerinin hepsinin daha yeni olması nedeniyle birinin girip bilgi sayfasının ekstra alıntılara referansını kopyalayacağını varsayıyorsunuz csh. Herkes Linux'ta GNU yardımcı programlarını çalıştırmaz; Aslında bunları, komutları sınırlı olan eski ticari Unix sistemlerine kurmak oldukça yaygındır. ( cshBu sistemlerde değişiklik yapılması daha az olasıdır, çünkü sistem komut dosyaları orijinalin cshcshroot
özdeşleştirmelerine dayanabilir

2
Hayır. Bir adamla tartışıyorum, vikimizde her zaman "{}" kullanımı önerisini vermemiz gerektiğini çünkü adam sayfasında da öyle diyor. Ve şimdi, kullanmadığım, ksh, zsh, tcsh, csh veya XYZsh gibi bilmediğim, bu iddianın doğru olduğu veya dürüst bir şekilde farz edebileceğimi kabul edebileceğim bir kabuk olup olmadığını bilmek istiyorum. yok. "{}" Gerektiren farklı Unix'ler için mermiler varsa, bu cümlenin neden hala adam sayfasında olduğunu ancak linux yeni başlayanlar için tavsiye olarak uygun olmadığını açık bir şekilde açıklayacaktır.
kullanıcı bilinmeyen,

Şimdi eğer merak ediyorum pdkshdoğru cevap rağmen ... doğru şeyi yapmıyor yani muhtemelen "gerçek kshFOSS bugünlerde".
geekosaur

4
Pdksh, mksh, ksh93, bash ve zsh gibi, yalnızca aralarında virgül olduğunda (veya ..ksh93, bash ve zsh için) parantezleri genişletir . Sadece (t) csh genişlediğinde {foo}için foo, ve hatta bırakır {}(en azından son BSD'lerin üzerine) yalnız.
Gilles 'SO- kötü kalmayı'
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.