Pętla w podkatalogach i uruchamianie poleceń w każdym z nich


47

Mam zestaw repozytoriów posortowanych w katalogach na podstawie ich VCS (Git, Mercurial, SVN). Dzięki Subversion mogłem uruchomić svn update *w katalogu nadrzędnym, który przechodziłby przez każdy katalog i aktualizował każde repozytorium zgodnie z oczekiwaniami. Tak nie jest w przypadku Git lub Mercurial.

Chciałbym wymyślić skrypt bash, który mogę uruchomić, aby dokładnie to zrobić, przeglądać katalogi i jedno git pulllub drugie hg pull. Po prostu nie mam dużego doświadczenia w tworzeniu skryptów bash.


Można wyjaśnić, czy chcesz, aby polecenia były wykonywane rekurencyjnie (we wszystkich podfolderach), gdzie odpowiedź mj41 jest jedyną, której próbowałem (stąd i na innych stronach SO), która to robi.
r_alex_hall

* robi to z poprawką, o której wspominam w komentarzu na ten temat.
r_alex_hall

Odpowiedzi:


81
for dir in ~/projects/git/*; do (cd "$dir" && git pull); done

2
Dzięki ... ale muszę też wychwytywać błędy. Jak mogę to zrobić? Nigdy wcześniej nie programowałem w powłoce.
shashwat

23

Jeśli potrzebujesz rekurencji:

find . -type d -name .git -exec sh -c "cd \"{}\"/../ && pwd && git pull" \;

Spowoduje to zejście do wszystkich katalogów pod bieżącym i wykonanie ściągnięcia git na te podkatalogi, które mają katalog .git (możesz go ograniczyć -maxdepth).


@thprivileges: clever!
Dennis Williamson

9
-execdirjest tu znacznie lepiej:find . -type d -name .git -execdir sh -c "pwd && git pull" \;
Daniel Kullmann

To jest lepsza odpowiedź w mojej subiektywnej opinii ... Od razu
zadziałało

W przeciwieństwie do pytania, które mnie tu połączyło, to polecenie faktycznie działało. Dziękuję Ci.
user1445967

7

Jeśli masz GNU Parallel http: // www.gnu.org/software/parallel/, możesz to zrobić:

cd ~/projects/git/; ls | parallel 'cd {} && git pull'

Będzie to działało równolegle, więc jeśli niektóre połączenia sieciowe serwerów git są wolne, może to przyspieszyć.

Obejrzyj wideo wprowadzające do GNU Parallel, aby dowiedzieć się więcej: http://www.youtube.com/watch?v=OpaiGYxkSuQ


Być może ls */upewnij się, że dajesz spójny wkład cd.
Joe Corneli,

4

To powinno działać

find . -maxdepth 1 -type d -name '.git' -exec sh -c 'cd "{}" && pwd && git pull' \;

usuwając -maxdepth 1flagę, jest to jedyne polecenie, które znalazłem podczas wielu wyszukiwań i prób, które wykonuje polecenie rekurencyjnie (we wszystkich podkatalogach, nie tylko w katalogach o jeden poziom niżej).
r_alex_hall

0

Aby to zrobić rekurencyjnie bez użycia, findaleforloop

for dir in ~/projects/git/*/*/; do (cd "$dir" && git pull); done
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.