Sambil menyelesaikan beberapa tantangan KKP online, saya menemukan situasi di mana saya perlu memperkuat server. Ini adalah kode yang saya tulis:
#!/bin/bash
for i in {0..9}{0..9}{0..9}{0..9}
do
echo "Now trying code.."
echo $i
echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt
done
Ini luar biasa, sangat lambat . Saya perlu mencoba kombinasi dari 1000 hingga 9999 dan ini membutuhkan waktu sekitar 5 detik untuk setiap 10 percobaan. Kemudian, mengikuti saran, saya meletakkan tanda '&' di akhir baris ini:
echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt &
Dan, ia mencoba kombinasi 100-an dalam hitungan detik. Saya sangat terkejut. Bisakah seseorang menjelaskan logikanya kepada saya? Apa yang dilakukan '&'?
bash
shell-script
command-line
pelajarX
sumber
sumber
&
membuat perintah berjalan di latar belakang, itu saja. Itu tidak membuatnya lebih cepat atau apa pun. Baca manual shell yang Anda gunakan (saya asumsikan bash) manual.for i in {1000..9999}
wait
di bagian akhir.nc -z localhost 1000-2000
?Jawaban:
Menambahkan
&
memunculkan proses latar belakang.Jika Anda menulis
a; b
, itu akan menjalankan perintaha
, tunggu sampai selesai, kemudian jalankan perintahb
, secara berurutan.Jika Anda menulis
a & b
, itu akan muncula
sebagai proses latar belakang. Itu tidak akan menunggu sampai selesai, dan itu akan mulai berjalanb
segera. Ini akan menjalankan keduanya sekaligus.Anda dapat melihat apa yang dilakukannya dengan bereksperimen di shell. Jika Anda telah
X
menginstal,xterm
adalah cara yang baik untuk melihat apa yang terjadi: mengetikakan menyebabkan jendela terminal lain terbuka, dan yang pertama akan menunggu sampai Anda menutupnya. Hanya ketika Anda menutupnya Anda akan mendapatkan shell Anda kembali. Jika Anda mengetik
maka itu akan menjalankannya di latar belakang, dan Anda akan mendapatkan shell Anda segera, sementara
xterm
jendela juga akan tetap terbuka.Jadi, jika Anda menulis
itu membuat koneksi, mengirim string, menyimpan apa yang keluar dalam file, dan hanya kemudian pindah ke yang berikutnya.
Menambahkan
&
membuatnya tidak menunggu. Ini akan berakhir menjalankan semua sepuluh ribu dari mereka lebih atau kurang secara bersamaan.Skrip Anda tampaknya "berakhir" lebih cepat, karena mungkin itu tidak benar-benar selesai pada saat itu. Itu hanya membuat sepuluh ribu pekerjaan latar belakang, dan kemudian mengakhiri latar depan.
Ini juga berarti bahwa, dalam kasus Anda, itu akan mencoba membuka sepuluh ribu koneksi lebih atau kurang sekaligus. Bergantung pada apa yang ujungnya bisa tangani, beberapa dari mereka mungkin gagal. Bukan hanya itu, tetapi tidak ada jaminan bahwa mereka akan berjalan berurutan, pada kenyataannya mereka hampir pasti tidak akan, jadi apa yang sebenarnya akan berakhir
/tmp/me/dump.txt
adalah dugaan siapa pun.Apakah Anda memeriksa apakah outputnya benar?
sumber
$ cat dump.txt | sort | uniq -u
..dan baris yang berisi kata sandi yang benar terungkap kepada saya.nc
buffer tulis. Seandainya tidak demikian, respons server kemungkinan besar akan disisipkan. Yaitu, jika Anda memiliki buffer tulis 1 byte, dan tanggapannya1111
dan2222
, Anda mungkin akan melihat sesuatu seperti11221212
daripada dipisahkan dengan rapi1111 2222
.Perintah nc (netcat) mahal, waktu bijaksana. Perlu terhubung ke server jarak jauh, mengirim data, menunggu respons, dan mengembalikannya.
Dengan menggunakan & Anda pada dasarnya forking perintah itu dalam proses latar belakang (itu disebut "pekerjaan"). Dengan sendirinya itu tidak membuatnya berjalan lebih cepat. Tetapi itu berarti loop Anda tidak lagi diblokir, dan dapat melakukan iterasi berikutnya (dengan nc berikutnya) sudah.
Jadi pada dasarnya, speedup Anda disebabkan oleh membuat semua koneksi jarak jauh ini secara paralel di mana jika tidak mereka harus menunggu yang sebelumnya selesai.
Btw, tergantung pada terminal Anda, perintah gema juga dapat memperlambat loop Anda (kadang-kadang mereka harus menunggu sampai ada ruang di buffer tulis).
sumber