Bash genişlemesinin argüman olarak “-” ile başlayan dosyaları geçirmesini nasıl önleyebilirim?


14

Ben özyinelemeli bir dize aramak çalışıyorum grepama bunu elde:

$ grep -r "stuff" *
grep: unrecognized option '---corporate-discount.csv'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

Bash'in -argüman olarak başlayan dosyaları geçirmesini nasıl önleyebilirim ?



3
Kabuğun bu dosyaları geçirmesini gerçekten istemiyorsunuz, değil mi? Asıl soru, grepseçenek olmadığını söylemek .
DonHolgo

11
... açık olmak gerekirse, bash hangi sonuçların seçenek olarak değerlendirildiğini argüman olarak değerlendirmez; bu alıcı programın kontrolündedir. Aynı davranışı, örneğin subprocess.Popen(['grep', '-r', '-e' 'stuff', '--corporate-discount.csv'])Python'da, hiçbir yerde bash ile elde edersiniz .
Charles Duffy

1
İlgili okuma: Unix Wildcards Gone Wild , *komutlarda kullanılmasından kaynaklanabilecek güvenlik sorunları hakkında . Bunların TÜMÜ kullanılarak ./*yerine önlenebilir .
Joker

1
@Wildcard, --seçenek sonu sigil olarak kullanmak da oldukça makul; POSIX yardımcı programı söz dizimi yönergelerine uyulmasını gerektirir; 10 numaralı kılavuza bakın. (Elbette, tüm programlar POSIX yönergelerine uymaz, ancak cevap rahatsız edici programların yazarlarını dizmek ve / veya bunları sektörden çıkarmaktır).
Charles Duffy

Yanıtlar:


43

İlk olarak, tire ile başlayan argümanların yorumunun başlatılan programa grepveya başka bir programa bağlı olduğunu unutmayın . Kabuğun onu kontrol etmenin doğrudan bir yolu yoktur.

Bu tür dosyaları işlemek istediğinizi varsayarsak (ve tamamen yok saymazsınız), grepçoğu programla birlikte --, seçeneklerin sonunu belirten olarak kabul eder, bu nedenle

grep -r -e "stuff" -- *

ne istersen yapacak. -eDurumda orada stuffbir ile başlar -sıra.

Alternatif olarak şunları da kullanabilirsiniz:

grep -r -e "stuff"  ./*

-Geçerli dizinde çağrılan bir dosya varsa, bu sonuncusu da sorunu önler . --Ayırıcıdan sonra bile , geçerli dizinde çağrılan dosyayken, stdin anlamı olarak grepyorumlanır .-./--


8

Bash genişletmesinin “-” ile başlayan dosyaları geçirmesini önlemek için şunları kullanabilirsiniz:

echo [!-]*

Çoğu kabukta taşınabilir olarak çalışır veya ksh, bash, zsh'ye özgü:

echo !(-*)

Örneğin: bu dosyaları içeren bir dizinde

$ echo *
a b c ---corporate-discount.csv d -e --option.txt

Yalnızca listelenecek (sağlanan extglobetkin):

$ shopt -s extglob
$ echo !(-*)
a b c d

$ echo [!-]*
a b c d

Ancak, grep'e a ile belirtilen dosyaları yorumlamamasını söylerken tüm dosyaları işlemek istiyorsanız, -sadece bir ekleyin ./:

grep -r "stuff" ./*

Veya, -listelenen dosyalarda tam olarak adlandırılan hiçbir dosyanın bulunmadığının garantisi varsa (grep, yalnız stdin'den okundu- olarak yorumlanır ), şunları kullanabilirsiniz:

grep -r -- "stuff" *

Evet, soru bash, bir GNU kabuğu ile ilgili olduğu için, bir GNU grep'in mevcut olduğunu, kurulabileceğini veya aslında kullanıldığını varsaymak mantıklı görünüyor. StéphaneChazelas
Isaac

Evet, a grep -r -- stuff *daha basittir ve GNUish olmayan grepslerle de çalışır. Yani: eklendi, teşekkürler. StéphaneChazelas
Isaac

@Isaac "Bash varsa, GNU grep de mevcuttur" diye makul bir varsayım olduğunu söyleyemem. Örneğin FreeBSD: bash varsayılan olarak yüklenmez, bu daha sonra yüklenebilir, ancak grep üzerinde bir etkisi yoktur - GNU grep açıkça yüklenmedikçe grep'in BSD sürümü olarak kalır. Ama bu küçük bir nitpick. Extglob üzerinden alternatif yaklaşımı seviyorum, dolayısıyla cevabı + 1'ed
Sergiy Kolodyazhnyy

2
@SergiyKolodyazhnyy, AFAIK, grepFreeBSD üzerinde hala GNU'yu temel alıyor grepve seçeneklerin seçeneklerden sonra tanındığı yanlış özelliklere sahip. OpenBSD gibi yeniden yazmış olan BSD'ler bile greponları geri taşınabilirlik için GNU uyumlu hale getirdi (ve yine de bu davranışı burada gösteriyor). MacOS'ta sh bash, ama greplerinin macOS olarak davranışın $ POSIXLY_CORRECT olmadan bile POSIX uyumlu olması gerektiğini göstermemesini beklerdim. Her durumda, OP'nin grep'i bu hatayı verdiği için GNU uyumludur.
Stéphane Chazelas

1
Ayrıca echo [!-]*, ksh (veya bash -O extglob's)' ın standart eşdeğeri olarak da bakın echo !(-*).
Stéphane Chazelas
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.