Recorriendo los subdirectorios y ejecutando un comando en cada uno

47

Tengo un conjunto de repositorios ordenados en directorios basados ​​en su VCS (Git, Mercurial, SVN). Con Subversion pude ejecutar svn update *en el directorio principal y recorría cada directorio y actualizaba cada repositorio como se esperaba. Ese no es el caso de Git o Mercurial.

Me gustaría llegar a un script bash que no puedo correr a hacer exactamente eso, bucle a través de los directorios y, o bien git pullo hg pullen cada uno. Simplemente no tengo mucha experiencia en scripting bash.

Bryan Veloso
fuente
Podría aclararse si desea que los comandos se ejecuten de forma recursiva (en todas las subcarpetas), donde la respuesta de mj41 es la única que he intentado (desde aquí y en otros sitios SO) que hace eso.
r_alex_hall
* lo hace con un ajuste que menciono en un comentario al respecto.
r_alex_hall

Respuestas:

81
for dir in ~/projects/git/*; do (cd "$dir" && git pull); done
jtimberman
fuente
2
Thnx ... pero también necesito capturar errores. Como lo puedo hacer. Nunca he hecho programación de shell antes.
shashwat
23

Si necesita que sea recursivo:

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

Esto descenderá a todos los directorios bajo el actual, y realizará un git pull en esos subdirectorios que tienen un directorio .git (puede limitarlo con -maxdepth).

Pausado hasta nuevo aviso.
fuente
@thprivileges: ¡listo!
Pausado hasta nuevo aviso.
99
-execdires mucho mejor aquí:find . -type d -name .git -execdir sh -c "pwd && git pull" \;
daniel kullmann
Esta es una mejor respuesta en mi opinión subjetiva ... Trabajó de inmediato para mí .. Saludos
Voke Ransom Anighoro
A diferencia de la pregunta que me vinculó aquí, este comando realmente funcionó. Gracias.
user1445967
7

Si tiene instalado GNU Parallel http: // www.gnu.org/software/parallel/, puede hacer esto:

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

Esto se ejecutará en paralelo, por lo que si algunas de las conexiones de red de los servidores git son lentas, esto puede acelerar las cosas.

Mire el video de introducción de GNU Parallel para obtener más información: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
fuente
Quizás lo haga ls */para asegurarse de que está dando una entrada coherente cd.
Joe Corneli
4

Esto debería funcionar

find . -maxdepth 1 -type d -name '.git' -exec sh -c 'cd "{}" && pwd && git pull' \;
mj41
fuente
eliminando la -maxdepth 1bandera, este es el único comando que he encontrado en muchas búsquedas e intentos que ejecuta un comando de forma recursiva (en todos los subdirectorios, no solo en los directorios un nivel por debajo).
r_alex_hall
0

Para hacerlo recursivo sin usar findperoforloop

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