Bash Globbing Nedir ve Wildcard Kullanımı
Bash globbing mekanizmasının dosya isimlerini nasıl genişlettiğini ve wildcard karakterlerini öğrenin. nullglob, dotglob, globstar ve extglob ayarlarını detaylıca inceleyin.
Komutunuz çalışmadan önce bash globbing işleminin yaptığı
Bash globbing, komut başlamadan önce kabuğun *.log gibi bir kalıbı, gerçek dosya adlarından oluşan sıralı bir listeye dönüştürme işlemidir. rm *.log, rm öğesine hiçbir zaman bir kalıp iletmez. Bash dizini okur, eşleşen adları tutar, bunları sıralar ve ardından her bir adı ayrı bir argüman olarak kullanarak rm komutunu çalıştırır. rm programı, sürecin herhangi bir aşamasında bir kalıp kullanıldığını anlayamaz.
Globbing ile ilgili şaşırtıcı olan hemen hemen her şey bu tek gerçeğe dayanır. Eşleştirme işlemi kabuk tarafından, o anda mevcut olan dosyalara göre yapılır ve komut yalnızca sonuç listesini görür. Bunun resmi adı yol adı genişletmedir (pathname expansion). Globbing ise günlük dilde kullanılan terimdir ve her ikisi de aynı anlama gelir.
Pratik yapmak için küçük bir ağaç yapısı oluşturun
Aşağıdaki tüm örnekler aynı dosyalar üzerinde çalışır. Bunları geçici bir dizinde oluşturun; böylece önemli verileriniz etkilenmez ve temizlik tek bir komutla tamamlanır.
lab=$(mktemp -d)
cd "$lab"
mkdir -p logs archive/2025 archive/2026
touch app.log app.log.1 app.log.2 app.log.10 error.log debug.LOG
touch notes.txt notes.md README 'weekly report.log'
touch .env .apprc
touch logs/nginx.log logs/nginx.log.1
touch archive/2025/dec.log archive/2026/jan.logmktemp -d yeni bir dizin oluşturur ve yolunu döndürür, $(...) ise bu yolu lab değişkenine atar. Bu sözdizimi sizin için yeniyse, komut değiştirmenin komut çıktısını nasıl yakaladığı konusu bunu tüm detaylarıyla açıklar.
Oluşturduğunuz yapıya bakın ve kabuğunuzu kontrol edin; çünkü sondaki bir not sürüme bağlıdır:
ls -a
bash --versionBuradaki her şey bash 4.0 ve sonraki sürümlerde çalışır. Sondaki globskipdots notu, Ağustos 2026 itibarıyla güncel Ubuntu ve Debian sürümlerinde yüklü gelen bash 5.2 ve sonraki sürümler için geçerlidir.
Genelinde kullanılan önizleme komutu printf '%s\n' PATTERN'dir. Bu komut, her satırda bir eşleşme yazdırır ve disk üzerinde hiçbir şeyi değiştirmez; bu nedenle emin olmadığınız herhangi bir desen üzerinde çalıştırmak güvenlidir.
Üç joker karakter: yıldız, soru işareti ve köşeli parantezler
*boş olanlar dahil olmak üzere herhangi bir karakter dizisiyle eşleşir.?tam olarak bir karakterle eşleşir.[...]köşeli parantez içindeki kümeden alınan tam olarak bir karakterle eşleşir.
printf '%s\n' *.log
printf '%s\n' app.log.?
printf '%s\n' app.log.[0-9]
printf '%s\n' notes.*
printf '%s\n' *İkinci satırı oluşturduğunuz dosya listesiyle karşılaştırın. ? tek bir karakteri temsil eder ve fazlasını kapsamaz, bu nedenle iki haneli bir son ek bu kalıbın dışında kalır. Kapsamı app.log.[0-9]* olacak şekilde genişletin ve farkı görmek için tekrar çalıştırın.
Üç joker karakterin tamamı için iki kural geçerlidir. Hiçbir joker karakter bir / ile eşleşmez, bu nedenle bir kalıp tek bir dizin seviyesi içinde kalır. Ayrıca, başta yer alan bir . karakterinin doğrudan yazılması gerekir, bu yüzden * ile başlayan bir kalıp tüm gizli dosyaları atlar. Bu ikinci kural, rm * komutunun nokta ile başlayan dosyalarınızı (dotfiles) neden etkilemediğini açıklar.
Glob sonuçları, mevcut yerel ayarın (locale) sıralama düzeni kullanılarak alfabetik olarak sıralanır; bu, karakter karakter yapılan bir metin sıralamasıdır. Bu nedenle, 10 son eki 2 son ekinden önce gelir, çünkü karşılaştırma işlemi hiçbirini sayı olarak değerlendirmez. printf '%s\n' app.log.* ve ardından ls -v app.log.* komutlarını çalıştırıp ikisini karşılaştırın: ls -v gömülü sayıları değerlerine göre sıralar, sort -V ise aynı işlemi bir boru hattı (pipeline) içinde gerçekleştirir.
Karakter sınıfları ve aralıkları
Köşeli parantezlerin içine bir liste, bir aralık veya bir olumsuzlama yazabilirsiniz.
[ch],cveyahkarakterlerinden birini eşleştirir.[a-f], a'dan f'ye kadar olan aralıktaki bir karakteri eşleştirir.[!0-9], rakam olmayan bir karakteri eşleştirir.[^0-9]de aynı anlama gelir.
printf '%s\n' [dn]*
printf '%s\n' *.[A-Z]*
printf '%s\n' [A-Z]*Aralıklar, makineler arasında tutarsızlık yaratan kısımdır. Bir aralık, düz ASCII yerine mevcut yerel ayarın (locale) sıralama düzenine göre çözümlenir; bu nedenle bazı sistemlerde [a-z] büyük harfleri de eşleştirebilir. Bash, düz ASCII sıralamasını zorunlu kılan bir globasciiranges seçeneğine sahiptir ve güncel sürümlerde bu özellik varsayılan olarak etkindir; bu yüzden varsayımda bulunmak yerine shopt globasciiranges ile kendi sisteminizi kontrol edin. Her yerde aynı şekilde eşleşmesi gereken bir betik, en üst kısımda tek başına bir satıra LC_ALL=C ataması yaparak sıralamayı sabitleyebilir; bu işlem tüm aralıkları tekrar düz bayt sıralamasına döndürür.
Bu atama, kendi başına bir komut olmalıdır. Bir önek olarak yazıldığında LC_ALL=C ls [a-z]*, yerel ayarı yalnızca ls için belirler; kabuk, ls başlamadan önce kalıbı kendi yerel ayarında çoktan genişletmiş olur ki bu da ilk bölümde görülen kuralın tekrarıdır.
Küme parantezi genişletmesi (brace expansion) globbing değildir
Küme parantezleri joker karakter gibi görünür ancak işleyişleri tamamen farklıdır. Küme parantezi genişletmesi, globbing işleminden çok daha önce çalışır ve disk üzerinde hiçbir kontrol yapmaz.
echo file{1,2,3}.txt
echo {01..10}
echo {a..e}
echo {0..20..5}Bu dosyaların hiçbiri mevcut değildir ancak genişletme işlemi yine de gerçekleşir. Aradaki temel fark budur: glob, dosya sistemine bir soru sorarken, küme parantezi sadece metin üretir. Küme parantezlerinin bir şeyleri bulmak yerine oluşturmak için doğru araç olmasının nedeni de budur.
mkdir -p site/{css,js,img}
cp app.log{,.bak}
touch report-{2025,2026}-{01,02}.csvcp app.log{,.bak} ifadesi, virgülden önceki boş öğe orijinal metni yeniden ürettiği için app.log ve app.log.bak olmak üzere iki kelimeye genişler. {01..10} ifadesi, sıfır dolgusunu korur; çünkü uç noktalardan herhangi birinin başında sıfır olması, bash'in üretilen her sayıyı aynı genişliğe getirmesini sağlar.
Genişletme sırası, kullanıcıların sıkça karşılaştığı bir hatayı da açıklar. Bash önce küme parantezlerini, ardından değişkenleri genişletir ve en son yol adı genişletmesini (pathname expansion) yapar.
n=5
echo {1..$n}$n bir sayıya dönüştüğünde küme parantezi genişletmesi çoktan tamamlanmış olur, bu nedenle hiçbir aralık oluşturulmaz. Bunun yerine seq 1 "$n" kullanın veya for ((i=1; i<=n; i++)) şeklinde yazılmış C tarzı bir döngü tercih edin.
Bir desen hiçbir şeyle eşleşmediğinde ne olur
Bu, ilk hata modudur ve herkesi en az bir kez yakalar. Varsayılan olarak bash, eşleşmeyen bir deseni olduğu gibi bırakır. Kelime, komuta tam olarak yazdığınız şekilde ulaşır; dolayısıyla komut *, ., t, m ve p karakterlerini alır ve bunları bir dosya adı olarak işlemeye çalışır.
printf '%s\n' *.tmpBu durum printf ile zararsızdır. Ancak bir şeyler oluşturan bir komutla zararsız değildir. .tmp dosyası bulunmayan bir dizinde touch *.tmp çalıştırmak, adı tam olarak *.tmp olan bir dosya oluşturur. Bunu daha sonra silmek için kabuğun tekrar genişletme yapmaması adına tırnak işareti kullanmak gerekir: rm -- '*.tmp'.
İki kabuk seçeneği bu kuralı değiştirir. Her birini hiçbir şeyle eşleşmeyen bir desen üzerinde deneyin ve ardından ayarı kaldırın.
shopt -s nullglob
printf '%s\n' *.tmp
shopt -u nullglob
shopt -s failglob
printf '%s\n' *.tmp
shopt -u failglobnullglob, eşleşmeyen bir desenin hiçbir şeye genişletilmemesini sağlar; böylece komut yazdığınızdan daha az argümanla çalışır. Bir döngü içerisinde istediğiniz davranış budur. nullglob kapalıyken, for f in *.tmp gövdesi f değişkeni içinde desenin kendisini tutarak bir kez çalışır; bu, bunu yapan neredeyse tüm betiklerde bir hatadır. nullglob açıkken, gövde sıfır kez çalışır.
nullglob kendi tehlikesini beraberinde getirir, çünkü tüm argümanlarından arındırılmış bir komut yine de çalışır. ls *.nope, tüm dizini listeleyen yalın bir ls komutuna dönüşür. grep -l needle *.nope ise okunacak dosyası kalmadığı için grep -l needle haline gelir; bu durumda standart girdiyi bekler ve donmuş gibi görünür. nullglob seçeneğini yalnızca ihtiyaç duyduğunuz döngü etrafında açın ve sonrasında tekrar kapatın.
failglob diğer yolu izler: eşleşmeyen bir desen hatadır, bash bunu raporlar ve komut hiçbir şekilde çalışmaz. Bu, etkileşimli bir kabuk için iyi bir ayardır çünkü yanlış yazılmış bir desenin rm komutuna gerçek bir isim olarak iletilmesini engeller.
Gizli dosyalar: dotglob
shopt -s dotglob
printf '%s\n' *
shopt -u dotglobBu bloğu çalıştırın ve listelemeyi daha önceki printf '%s\n' * ile karşılaştırın. dotglob, başta nokta olma kuralını kaldırır; bu sayede * gizli isimleri de eşleştirir. . ve .. girdileri, dotglob aktif olsa dahi her zaman hariç tutulur.
dotglob olmadan, gizli dosyalara ulaşmanın alışılagelmiş yolu .* kullanmaktır ve bu yöntem eskiden tehlikeliydi. 5.2 öncesi bash sürümlerinde .*, . ve .. ile de eşleşiyordu; bu nedenle chmod -R 755 .* gibi özyinelemeli bir komut doğrudan üst dizine giriyordu. Bash 5.2, varsayılan olarak etkin gelen globskipdots seçeneğini ekledi. Bu seçenek, . ve .. öğelerini her genişletme işleminden uzak tutar. Buna güvenmeden önce shopt globskipdots komutunu çalıştırın, çünkü eski sistemlerde bu özellik bulunmayacaktır.
globstar: dizin ağacının tamamında eşleştirme
shopt -s globstar
printf '%s\n' **/*.log
printf '%s\n' **/
shopt -u globstarglobstar ayarlandığında, bir tam yol bileşeni oluşturan **, sıfır seviye derinlik dahil olmak üzere herhangi bir derinlikteki dosya ve dizinlerle eşleşir. Bu sayede **/*.log, mevcut dizini, logs/ dizinini ve archive/ altındaki her şeyi kapsar. Sondaki eğik çizgi (slash) ile kullanılan bir **/ yalnızca dizinlerle eşleşir; bu, bir dizin ağacının yapısını görmenin hızlı bir yoludur.
globstar ayarlanmadığında, ** sıradan bir * gibi davranır ve yalnızca tek bir dizin içinde kalır. Aynı deseni seçenek kapalıyken çalıştırıp karşılaştırın: başka bir yerden kopyalanan ve beklediğinizden çok daha az sonuç döndüren özyinelemeli (recursive) bir desenin nedeni genellikle budur. globstar, tüm bash sürümlerinde varsayılan olarak kapalıdır.
Bilinmesi gereken bir sınırlama: **, dizinlere giden sembolik bağlantıları (symlink) takip etmez. Sembolik bağlantılarla birbirine bağlanmış bir ağaç yapısı için bunun yerine find -L kullanılmalıdır.
nocaseglob, büyük/küçük harf duyarlılığı farklı olan isimler için
shopt -s nocaseglob
printf '%s\n' *.log
shopt -u nocaseglobnocaseglob, dosya adı eşleştirmesinin büyük/küçük harf ayrımı yapmamasını sağlar; böylece büyük harfli bir .LOG soneki, küçük harfli bir .log kalıbıyla eşleşir. Bu listelemeyi ilk bölümdeki ile karşılaştırın. Seçeneği hemen tekrar kapatın; çünkü açık bırakıldığında, o shell içinde izleyen tüm komutlar için eşleştirme mantığını değiştirir ve bu durum bir saat sonra hata ayıklarken kafa karıştırıcı olabilir.
nocaseglob yalnızca dosya adı genişletme (filename expansion) için geçerlidir. Bir case ifadesi veya çift köşeli parantez testi içindeki kalıp eşleştirme için ilgili seçenek nocasematch olup, bu ikisi birbirinden ayrı olarak ayarlanır.
extglob: "bunu hariç tut" diyen desenler
Genişletilmiş desenler varsayılan olarak kapalıdır. Bunları kendi satırlarında şu şekilde açın:
shopt -s extglobHer biri | ile ayrılmış desen listeleri alan beş biçim mevcuttur:
?(list)sıfır veya bir eşleşme sağlar.*(list)sıfır veya daha fazla eşleşme sağlar.+(list)bir veya daha fazla eşleşme sağlar.@(list)alternatiflerden tam olarak birini eşleştirir.!(list)alternatiflerden hiçbirine uymayan her şeyi eşleştirir.
Genişletilmiş bir desen, seçeneğin zaten açık olduğu bir kabuk tarafından okunmalıdır; bu nedenle aşağıdaki toplu işlem, bash -O extglob ile başlatılan küçük bir betik içinde yer alır. -O bayrağı, yeni kabuk dosyanın tek bir satırını bile okumadan önce bir shopt seçeneğini ayarlar; bu da dosyadaki her desenin doğru şekilde ayrıştırılmasını sağlar. Bu bölümün son paragrafı, sıralamanın neden önemli olduğunun nedenidir.
cat > patterns.sh <<'EOF'
printf '%s\n' @(app|error).log
printf '%s\n' app.log.+([0-9])
printf '%s\n' *.@(md|txt)
printf '%s\n' !(*.log)
printf '%s\n' !(*.log|*.md|README)
EOF
bash -O extglob patterns.sh+([0-9]) bir veya daha fazla rakam anlamına gelir, bu nedenle herhangi bir uzunluktaki numaralandırılmış sonekleri kapsar. Bu, daha önceki ? sınırının çözümüdür ve her iki deseni de arka arkaya çalıştırıp görmek faydalıdır.
Olumsuzlama biçimi, "hariç her şey" sorusunun cevabıdır ve extglob özelliğini etkinleştirmenin asıl nedenidir. Bu konuyla ilgili iki durum kullanıcıları şaşırtır.
Bu biçim dosyaların yanı sıra dizinleri de eşleştirir; bu nedenle ls !(*.log), sonuçtaki dizin adını değil, dizinin içeriğini listeler. Adların kendisini görmek için ls -d veya printf önizlemesini kullanın.
Ayrıca diğer tüm glob ifadeleri gibi nokta kuralına uyar; bu nedenle !(*.log), .log ile bitmeyen tüm görünür adları kapsar. Gizli adlar için dotglob seçeneğinin de ayarlanması gerekir.
!(...) içindeki !, glob olumsuzlamasıdır. Bunun, farklı bir aşamada çalışan ayrı bir özellik olan geçmiş genişletme ve ünlem karakteri ile hiçbir bağlantısı yoktur.
Bir tuzak daha vardır ve bu ayrıştırma (parse) aşamasında gerçekleşir. Bash, bir komutun herhangi bir kısmını çalıştırmadan önce komutun tamamını ayrıştırır; bu nedenle extglob özelliğini etkinleştirip aynı satırda genişletilmiş bir desen kullanmak başarısız olur: desen, seçenek hala kapalıyken ayrıştırılır. shopt -s extglob komutunu kendi satırında, desenlerden önce ve betiğin üst kısımlarında tutun. Bir fonksiyon gövdesi, fonksiyon tanımlandığında ayrıştırılır; bu nedenle seçenek, çağrıdan önce değil, tanımdan önce açık olmalıdır. Yukarıdaki toplu işlemde olduğu gibi kabuğu bash -O extglob ile başlatmak, herhangi bir ayrıştırma başlamadan önce sıralama sorununu çözer.
Kabuk kalıbı genişletir, komut genişletmez
Bu, ikinci hata türüdür ve bir dizi hatanın nedenini açıklar.
grep -l needle *.log
find . -name '*.log'
find . -name *.logİlk satır eşleştirme işlemini bash'e bırakır ve grep bir dosya adı listesi alır. İkinci satır kalıbı tırnak içine alır, bu nedenle find beş karakterlik *.log dizisini alır ve başlangıç noktasının altındaki her derinlikte kendi eşleştirmesini yapar. Üçüncü satır hatalıdır: bash kalıbı önce yalnızca mevcut dizinde genişletir, bu yüzden find belirli bir ismi araması için yönlendirilir. Tek bir eşleşmenin olduğu dizinde, sessizce yanlış şeyi arar. İki veya daha fazla eşleşme olduğunda ise find bir kullanım hatası bildirir; çünkü fazladan isimler, bir ifade beklenen yere ulaşır.
Kural kısadır. Kalıp komut içinse tırnak içine alın. Kalıp kabuk içinse tırnak kullanmayın. Aynı ayrım tar ve rsync içindeki --exclude kalıpları ve grep içindeki --include filtreleri için de geçerlidir.
Glob ifadeleri, karakterleri paylaşsalar bile düzenli ifadeler (regular expressions) değildir. Bir glob ifadesinde *, herhangi bir karakter dizisi anlamına gelir. Düzenli ifadelerde ise *, kendisinden önce gelenin sıfır veya daha fazla tekrarı anlamına gelir; bu nedenle grep '*.log', göründüğünden çok farklı bir şey talep eder.
Değişkenler aynı işlem sırasını izler. Globbing işlemi değişken genişletmeden sonra çalışır, bu yüzden bir kalıp içeren tırnaksız değişken, dizin içeriğine göre genişletilir.
pat='*.log'
printf '%s\n' $pat
printf '%s\n' "$pat"Tırnaksız kullanımda bash, değişkenin sonucunu glob ile genişletir. Tırnaklı kullanımda ise kalıp olduğu gibi kalır. Güvenmeniz gereken ilgili bir sonuç daha vardır: globbing ile üretilen kelimeler boşluklara göre tekrar bölünmez; bu nedenle for f in *.log boşluk içeren bir dosya adını tek bir isim olarak işlerken, for f in $(ls *.log) bu ismi iki ayrı kelimeye böler. Glob ifadesi üzerinde doğrudan döngü kurun.
Yıkıcı bir kalıbı çalıştırmadan önce önizleyin
Yeni bir kalıbı denerken ilk komutunuzun asla rm olmasına izin vermeyin. Kalıbı zararsız bir komutla çalıştırın, listeyi okuyun ve ardından yalnızca satırın başındaki komutu değiştirin.
target='!(*.log)'
printf '%s\n' $target
ls -ld -- $target
rm -- $targetKalıbı bir kez target içine yazmak, üç satırın birbirinden farklılaşmasını engeller. $target kasıtlı olarak tırnak içine alınmamıştır; çünkü bash'in onu genişletmesini sağlayan budur. printf '%s\n' her satıra bir isim yazdırır ve hiçbir şeye dokunmaz. ls -ld dizinlerin içeriğini listelemek yerine her girdiyi kendisini gösterir; mod sütunu hangi girdilerin dizin olduğunu işaretler ki bu, herhangi bir özyinelemeli silme işleminden önce kontrol edilmesi gereken şeydir. drwxr-xr-x izin bitlerini okuma bu sütunu ele alır.
Önceki satırı yukarı ok tuşuyla geri çağırın ve yalnızca komutu düzenleyin; böylece kalıp aynı kalır. Bir kalıbı hafızadan tekrar yazmak, hataların sızdığı yerdir.
Kalıbın önüne -- koyun. Bu, seçeneklerin sonunu işaretler; böylece - ile başlayan bir dosya adı, bir bayrak yerine isim olarak işlenir.
Bir betiğin belirli bir bölümünde globbing özelliğini kapatmak isterseniz, set -f bunu devre dışı bırakır ve set +f tekrar açar.
Bu alışkanlık önemlidir çünkü rm işleminin geri dönüşü yoktur. rm -rf ile silinen dosyaları kurtarma yavaştır ve genellikle eksik sonuç verir; bu nedenle bir önizleme, alternatifinden çok daha az maliyetlidir.
İşiniz bittiğinde çalışma dizinini temizleyin. Önce yolu yazdırın ve okuyun; çünkü yanlış değişkene yönlendirilmiş bir rm -rf, tam olarak bu bölümün konusu olan kazadır.
cd ~
echo "$lab"
rm -rf -- "$lab"FAQ
find . -name *.log neden yanlış dosyaları buluyor?
Çünkü bash, find başlamadan önce *.log ifadesini genişletir. Kabuk, deseni mevcut dizinle eşleştirir ve ortaya çıkan dosya adını find komutuna iletir; bu komut da her derinlikte sadece o ismi arar. Eğer iki veya daha fazla dosya eşleşirse, find komutu bir ifade beklediği yerde fazladan argüman alır ve kullanım hatası bildirir. Deseni find . -name '*.log' şeklinde tırnak içine alın; böylece find eşleştirmeyi kendi kuralları ve kendi özyineleme (recursion) mantığıyla kendisi yapar.
Desenimin düz metin olarak görünmesi ne anlama gelir?
Hiçbir şeyin eşleşmediği anlamına gelir. Varsayılan olarak bash, eşleşmeyen bir deseni olduğu gibi bırakır ve ham karakterleri komuta iletir; komut da bunları bir dosya adı olarak işler. Eşleşmeyen bir deseni komutu durduran bir hataya dönüştürmek için shopt -s failglob ayarını yapın veya hiçbir şeyle genişlememesi için shopt -s nullglob seçeneğini kullanın. nullglob altındayken, komutun argümansız çalışıp çalışmadığını kontrol edin; çünkü ls *.nope boş bir ls haline gelir ve tüm dizini listeler.
bash içinde bir desen hariç her dosyayı nasıl eşleştiririm?
shopt -s extglob komutunu ayrı bir satırda kullanarak genişletilmiş desenleri etkinleştirin, ardından olumsuzlama biçimini kullanın. !(*.log), .log ile bitmeyen isimleri eşleştirir; !(*.log|*.md) ise her ikisini de hariç tutar. dotglob ayarlanmadığı sürece gizli dosyalar sonuçlara dahil edilmez ve dizinler dahil edilir; bu nedenle rm komutuna vermeden önce deseni printf '%s\n' !(*.log) ile önizleyin.
* neden gizli dosyaları atlıyor?
Başlangıçtaki nokta karakterinin birebir eşleşmesi gerekir, bu yüzden * ile başlayan bir isim asla eşleşmez. Gizli isimlere ulaşmak için .* kullanın veya tüm normal desenlere dahil etmek için shopt -s dotglob ayarını yapın. . ve .. girdileri dotglob altında her zaman hariç tutulur; bash 5.2 ve sonraki sürümler, varsayılan olarak açık olan globskipdots seçeneği sayesinde bunları .* kapsamından da uzak tutar.
** komutunun çalışması için globstar gerekli mi?
Evet. shopt -s globstar olmadan bash, ** ifadesini sıradan bir * olarak ele alır; bu da sadece bir dizin içinde eşleşir ve orada durur. globstar açıkken, tam bir yol bileşeni oluşturan ** her derinlikte eşleşir; bu sayede **/*.log mevcut dizine ve altındaki tüm dizinlere ulaşır, **/ ise tek başına sadece dizinleri eşleştirir. ** seçeneğinin dizinlere giden sembolik bağları takip etmediğini unutmayın; bu nedenle sembolik bağlardan oluşan bir ağaç yapısı için find -L kullanın.