Looping Melalui Subdirektori dan Menjalankan Perintah di Masing-Masing

47

Saya memiliki satu set repositori yang diurutkan ke dalam direktori berdasarkan VCS mereka (Git, Mercurial, SVN). Dengan Subversion saya dapat menjalankan svn update *di direktori induk dan itu akan berulang melalui setiap direktori dan memperbarui setiap repositori seperti yang diharapkan. Itu tidak berlaku untuk Git atau Mercurial.

Saya ingin membuat skrip bash yang dapat saya jalankan untuk melakukan hal itu, mengulangi direktori dan salah satu git pullatau hg pullmasing-masing. Saya hanya tidak memiliki banyak pengalaman bash scripting.

Bryan Veloso
sumber
Dapat diklarifikasi apakah Anda ingin perintah dieksekusi secara rekursif (di semua subfolder), di mana jawaban mj41 adalah satu-satunya yang saya coba (dari sini dan di situs SO lainnya) yang melakukan itu.
r_alex_hall
* melakukan itu dengan tweak yang saya sebutkan di komentar di atasnya.
r_alex_hall

Jawaban:

81
for dir in ~/projects/git/*; do (cd "$dir" && git pull); done
jtimberman
sumber
2
Thnx ... tetapi saya perlu menangkap kesalahan juga. Bagaimana saya bisa melakukannya? Saya belum pernah melakukan pemrograman shell sebelumnya.
shashwat
23

Jika Anda membutuhkannya untuk menjadi rekursif:

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

Ini akan turun ke semua direktori di bawah yang saat ini, dan melakukan tarikan git pada subdirektori yang memiliki direktori .git (Anda dapat membatasi dengan -maxdepth).

Dijeda sampai pemberitahuan lebih lanjut.
sumber
@thprivileges: pintar!
Dijeda sampai pemberitahuan lebih lanjut.
9
-execdirjauh lebih baik di sini:find . -type d -name .git -execdir sh -c "pwd && git pull" \;
daniel kullmann
Ini adalah jawaban yang lebih baik menurut pendapat subjektif saya ... Segera bekerja untuk saya .. Cheers
Voke Ransom Anighoro
Berbeda dengan pertanyaan yang menghubungkan saya di sini, perintah ini benar-benar berfungsi. Terima kasih.
user1445967
7

Jika Anda telah menginstal GNU Parallel http: // www.gnu.org/software/parallel/ Anda dapat melakukan ini:

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

Ini akan berjalan secara paralel sehingga jika beberapa koneksi jaringan server git lambat ini dapat mempercepat beberapa hal.

Tonton video intro untuk GNU Parallel untuk mempelajari lebih lanjut: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
sumber
Mungkin lakukan ls */untuk memastikan Anda memberikan masukan yang masuk akal cd.
Joe Corneli
4

Ini seharusnya bekerja

find . -maxdepth 1 -type d -name '.git' -exec sh -c 'cd "{}" && pwd && git pull' \;
mj41
sumber
menghapus -maxdepth 1bendera, ini adalah satu-satunya perintah yang saya temukan di banyak pencarian dan mencoba yang mengeksekusi perintah secara rekursif (di semua subdirektori, bukan hanya direktori satu tingkat ke bawah).
r_alex_hall
0

Untuk melakukannya secara rekursif tanpa menggunakan findtetapiforloop

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