Mengambil " Bash saja dan tidak ada yang lain " dengan ketat, inilah satu adaptasi dari jawaban sebelumnya ( @ Chris's , @ 131's ) yang tidak memanggil utilitas eksternal apa pun (bahkan yang standar) tetapi juga berfungsi dengan file biner:
#!/bin/bash
download() {
read proto server path <<< "${1//"/"/ }"
DOC=/${path// //}
HOST=${server//:*}
PORT=${server//*:}
[[ x"${HOST}" == x"${PORT}" ]] && PORT=80
exec 3<>/dev/tcp/${HOST}/$PORT
# send request
echo -en "GET ${DOC} HTTP/1.0\r\nHost: ${HOST}\r\n\r\n" >&3
# read the header, it ends in a empty line (just CRLF)
while IFS= read -r line ; do
[[ "$line" == $'\r' ]] && break
done <&3
# read the data
nul='\0'
while IFS= read -d '' -r x || { nul=""; [ -n "$x" ]; }; do
printf "%s$nul" "$x"
done <&3
exec 3>&-
}
Gunakan dengan download http://path/to/file > file
.
Kami menangani byte NUL dengan read -d ''
. Bunyinya sampai byte NUL, dan mengembalikan true jika menemukan satu, false jika tidak. Bash tidak dapat menangani byte NUL dalam string, jadi ketika read
kembali dengan true, kami menambahkan byte NUL secara manual saat mencetak, dan ketika itu mengembalikan false, kita tahu tidak ada byte NUL lagi, dan ini harus menjadi bagian terakhir dari data .
Diuji dengan Bash 4.4 pada file dengan NUL di tengah, dan berakhir di nol, satu atau dua NUL, dan juga dengan wget
dan curl
binari dari Debian. wget
Biner 373 kB memerlukan waktu sekitar 5,7 detik untuk diunduh. Kecepatan sekitar 65 kB / dtk atau sedikit lebih dari 512 kb / dtk.
Sebagai perbandingan, solusi kucing @ 131 selesai dalam waktu kurang dari 0,1 detik, atau hampir seratus kali lebih cepat. Tidak terlalu mengejutkan, sungguh.
Ini jelas konyol, karena tanpa menggunakan utilitas eksternal, tidak banyak yang bisa kita lakukan dengan file yang diunduh, bahkan membuatnya tidak dapat dieksekusi.
gawk