Tüm dizinlere cd, bu dizindeki dosyalara komut çalıştırmak ve önceki geçerli dizine geri dönmek


41

Belirli bir dizinde çalıştırılacak bir komut dosyasını birçok tek düzey alt dizinle yazmayı deniyorum. Komut alt dizinlerin her birine cd, dizindeki dosyalara bir komut uygular ve bir sonraki dizine devam etmek için cd çıkar. Bunu yapmanın en iyi yolu nedir?


1
Verilen mevcut bilgi seviyesi göz önüne alındığında, hiçbir ilgisi olmadığını görüyorum youtube-dl.
HalosGhost

Yanıtlar:


83
for d in ./*/ ; do (cd "$d" && somecommand); done

12
Bu yüzden cevaplayıcı herhangi bir açıklama yapmadığından, bir tane deneyeceğim. for d in ./*/Her öğeyi ./*/bir değişkende (bu durumda bir dosya / klasör listesi) depolayan bir döngü başlatır $d. do (cd "$d" && somecommand);döngünün gövdesini başlatır. Vücudun içinde, bir alt kabuk başlatır cdve somecommandkomutları çalıştırır . Bir alt kabuk olduğundan, üst kabuk (bu komutu çalıştırdığınız kabuk) CWD ve diğer ortam değişkenlerini korur. donesadece döngü gövdesini kapatır.
Qix

Bu alt dizin dizinleri için bu yöntem çalışır:, for d in ./*/ ; do (cd "$d" && ls); doneçalışmaz. ama for d in ./*/ ; do (cd "$d" && for d in ./*/ ; do (cd "$d" && ls); done ); doneişe yarayacak. Bu örnekte komut olarak ls ile.
Michael Dimmitt

-bash: cd: ./*/: No such file or directory
S. Tarık Çetin

15

En iyi yol hiç kullanmamaktır cd:

find some/dir -type f -execdir somecommand {} \;

execdirgibidir exec, ancak çalışma dizini farklıdır:

   -execdir command {} [;|+]
          Like   -exec,   but  the  specified  command  is  run  from  the
          subdirectory containing the matched file, which is not  normally
          the  directory  in  which  you  started  find.  This a much more
          secure  method  for  invoking  commands,  as  it   avoids   race
          conditions  during resolution of the paths to the matched files.

POSIX değil.


Bu takma adlarla çalışıyor mu? Belirli dosyaları indirmek için bir tane var ama find * /. Link -type f -execdir md $ (cat .link) {} \;
Jones bir şey

@Bir şey yokJones hayır, findbu komutları uygular, böylece takma adların farkında olmaz. Dizin nedir mdve nedir .link?
muru

.link, indirmesi gereken URL’yi içeren bir metin dosyasıdır. md, birçok bayrak kümesiyle yazılacak takma addır. Diğer adların farkında olmanın bir yolu var mı?
Jones

@SomethingJones Özel kullanım durumunuz için, içinde bash: Bir dosyadan bir URL’yi okumak için bir bayrak bulunan , onunla işlem find . -type f -iname '*.link' -execdir ${BASH_ALIASES[md]} -i {} \;yapmanız gerekmez . Ayrıca bu, orijinal sorunuzdan biraz farklıdır (çünkü sadece adlandırılmış olan ve mevcut olabilecek başka herhangi bir dosyayla ilgilenmiyorsunuz ). catwget-i.link
muru

Bunu zsh ile nasıl yapacağını biliyor musun? Bana verdiğin şeyi denedim ve "Kötü oyuncu değişikliği" hatası alıyorum. Ayrıca, .link dosyasının içeriğini nasıl çıkarabilirim? Bu durumda ihtiyacım olmadığını biliyorum ama yakında göreceğimi tahmin ediyorum.
Jones bir şey

2
cd -P .
for dir in ./*/
do cd -P "$dir" ||continue
   printf %s\\n "$PWD" >&2
   command && cd "$OLDPWD" || 
! break; done || ! cd - >&2

Yukarıdaki komut herhangi altkabuklarda yapmak gerekmez - sadece ardışımı ile cari kabuğunda ilerlemesini izler $OLDPWDve $PWD. Siz cd -kabuk, bu iki değişkenin değerini değiştirdiğinde, temelde, dizinleri değiştirir. Ayrıca, stderr'de çalıştığı için her dizinin adını da yazdırır.

Sadece bir kez daha baktım ve hata yönetimi ile daha iyi bir iş çıkarmaya karar verdim. Başaramadığı bir dizini atlayacaktır cd- ve cdneden stderr olacağına dair bir mesaj yazacaktır - ve başarılı bir şekilde çalışmazsa veya bir şekilde çalıştırıyorsanız orijinal dizininize geri dönme özelliğini etkilerse breaksıfır olmayan bir çıkış kodu olacaktır. - . Bu durumda aynı zamanda bir son da yapar - ve elde edilen mevcut çalışma dizini adını stderr'ye yazar.commandcommand$OLDPWDcd -


1
for D in ./*; do
    if [ -d "$D" ]; then
        cd "$D"
        run_something
        cd ..
    fi
done
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.