Fazendo loop em subdiretórios e executando um comando em cada


47

Eu tenho um conjunto de repositórios classificados em diretórios com base em seus VCS (Git, Mercurial, SVN). Com o Subversion, eu era capaz de executar svn update *no diretório pai e ele percorria cada diretório e atualizava cada repositório conforme o esperado. Esse não é o caso do Git ou do Mercurial.

Gostaria de chegar a um script que eu posso correr para fazer exatamente isso, percorrer diretórios e ou git pullou hg pullem cada um. Eu simplesmente não tenho muita experiência com scripts bash.


Pode ser esclarecido se você deseja que os comandos sejam executados recursivamente (em todas as subpastas), onde a resposta do mj41 é a única que eu tentei (daqui e em outros sites da SO) que faz isso.
r_alex_hall 8/11

* faz isso com um ajuste que eu mencionei em um comentário.
r_alex_hall 8/11

Respostas:


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

2
Thnx ... mas eu preciso capturar erros também. Como eu posso fazer isso. Eu nunca fiz programação de shell antes.
Shashwat

23

Se você precisar que seja recursivo:

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

Isso irá descer para todos os diretórios abaixo do atual e executar um pull git nos subdiretórios que possuem um diretório .git (você pode limitá-lo -maxdepth).


@ privilégios: inteligente!
Dennis Williamson

9
-execdiré muito melhor aqui:find . -type d -name .git -execdir sh -c "pwd && git pull" \;
daniel kullmann

Esta é uma resposta melhor na minha opinião subjetiva ... Trabalhou imediatamente para mim .. Cheers
Voke Ransom Anighoro

Ao contrário da pergunta que me ligou aqui, esse comando realmente funcionou. Obrigado.
user1445967

7

Se você possui o GNU Parallel http: // www.gnu.org/software/parallel/ instalado, você pode fazer isso:

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

Isso será executado em paralelo, portanto, se a conexão de rede de alguns servidores git estiver lenta, isso poderá acelerar as coisas.

Assista ao vídeo de introdução do GNU Parallel para saber mais: http://www.youtube.com/watch?v=OpaiGYxkSuQ


Talvez faça ls */para ter certeza de que você está dando uma contribuição coerente cd.
1811 Joe Corneli

4

Isso deve funcionar

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

Ao remover o -maxdepth 1sinalizador, este é o único comando que encontrei em várias pesquisas e tentativas que executam um comando recursivamente (em todos os subdiretórios, não apenas nos diretórios de um nível abaixo).
r_alex_hall 8/11

0

Para fazê-lo recursivo sem usar, findmasforloop

for dir in ~/projects/git/*/*/; do (cd "$dir" && git pull); done
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.