Saya memiliki banyak gambar PNG di direktori. Saya memiliki aplikasi bernama pngout yang saya jalankan untuk mengompres gambar-gambar ini. Aplikasi ini disebut dengan script yang saya lakukan. Masalahnya adalah skrip ini melakukan satu per satu, seperti ini:
FILES=(./*.png)
for f in "${FILES[@]}"
do
echo "Processing $f file..."
# take action on each file. $f store current file name
./pngout -s0 $f R${f/\.\//}
done
Memproses hanya satu file pada satu waktu, membutuhkan banyak waktu. Setelah menjalankan aplikasi ini, saya melihat bahwa CPU hanya 10%. Jadi saya menemukan bahwa saya dapat membagi file-file ini dalam 4 batch, menempatkan setiap batch dalam direktori dan memecat 4, dari empat jendela terminal, empat proses, jadi saya memiliki empat contoh skrip saya, pada saat yang sama, memproses gambar-gambar dan pekerjaan membutuhkan 1/4 waktu.
Masalah kedua adalah saya kehilangan waktu untuk membagi gambar dan kumpulan dan menyalin naskah ke empat direktori, buka 4 terminal windows, bla bla ...
Bagaimana melakukannya dengan satu skrip, tanpa harus membagi apa pun?
Maksud saya dua hal: pertama bagaimana saya dari skrip bash, menjalankan proses ke latar belakang? (cukup tambahkan & ke akhir?) Kedua: bagaimana saya berhenti mengirim tugas ke latar belakang setelah mengirim tugas keempat dan menempatkan skrip untuk menunggu sampai tugas berakhir? Maksud saya, hanya mengirim tugas baru ke latar belakang sebagai salah satu tugas berakhir, menjaga selalu 4 tugas secara paralel? jika saya tidak melakukan itu, loop akan memuntahkan banyak tugas ke latar belakang dan CPU akan menyumbat.
sumber
Jawaban:
Jika Anda memiliki salinan
xargs
yang mendukung eksekusi paralel-P
, Anda dapat melakukannyaUntuk ide lain, wiki Wooledge Bash memiliki bagian dalam artikel Manajemen Proses yang menjelaskan dengan tepat apa yang Anda inginkan.
sumber
pngout
perintah yang ingin dijalankan OP. Opsi kuncinya adalah-P 4
, yang memberi tahu xargs untuk menggunakan hingga 4 perintah bersamaan.printf
fungsi di sini bukan hanya biasals .. | grep .. *.png
? Saya juga tertarik padaxargs
parameter yang Anda gunakan (-0
dan-I{}
). Terima kasih!ls
tidak dapat digunakan untuk mengurai nama file dengan mudah dan aman . Satu-satunya karakter aman yang digunakan untuk membatasi nama file adalah\0
dan/
, karena setiap karakter lain, termasuk\n
, dapat menjadi bagian dari nama file itu sendiri. Theprintf
penggunaan\0
untuk nama file membatasi, dan-0
menginformasikanxargs
ini. The-I{}
memberitahuxargs
untuk mengganti{}
dengan argumen.Selain solusi yang sudah diajukan, Anda dapat membuat makefile yang menjelaskan cara membuat file terkompresi dari tidak terkompresi, dan gunakan
make -j 4
untuk menjalankan 4 pekerjaan secara paralel. Masalahnya adalah Anda perlu memberi nama file terkompresi dan tidak dikompresi secara berbeda, atau menyimpannya di direktori yang berbeda, jika tidak menulis aturan make yang masuk akal tidak akan mungkin.sumber
Jika Anda telah menginstal GNU Parallel http://www.gnu.org/software/parallel/ Anda dapat melakukan ini:
Anda dapat menginstal GNU Parallel hanya dengan:
Tonton video intro untuk GNU Parallel untuk mempelajari lebih lanjut: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
sumber
Untuk menjawab dua pertanyaan Anda:
wait
perintah, Anda dapat meminta shell untuk menunggu semua proses di latar belakang selesai sebelum melanjutkan lebih jauh.Berikut skrip yang dimodifikasi sehingga
j
digunakan untuk melacak jumlah proses latar belakang. KetikaNB_CONCURRENT_PROCESSES
tercapai, skrip akan diatur ulangj
ke 0 dan menunggu semua proses latar belakang selesai sebelum melanjutkan kembali pelaksanaannya.sumber
$f
dll. (3) Gunakan[
untuk skrip yang kompatibel dengan POSIX, tetapi untuk bash murni[[
selalu lebih disukai. Dalam hal ini,((
lebih tepat untuk aritmatika.