Prendendo il " appena Bash e niente altro " strettamente, ecco un adattamento delle risposte precedenti ( @ Chris , @ 131 del ) che non chiamare qualsiasi utilità esterno (non anche quelli standard), ma funziona anche con i file binari:
#!/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>&-
}
Utilizzare con download http://path/to/file > file
.
Abbiamo a che fare con byte NUL con read -d ''
. Legge fino a un byte NUL e restituisce true se ne trova uno, false in caso contrario. Bash non è in grado di gestire i byte NUL nelle stringhe, quindi quando read
ritorna con true, aggiungiamo manualmente il byte NUL durante la stampa e quando restituisce false, sappiamo che non ci sono più byte NUL e questo dovrebbe essere l'ultimo pezzo di dati .
Testato con Bash 4.4 sui file con NUL nel mezzo, e termina a zero, uno o due NULs, e anche con l' wget
e curl
binari da Debian. Il wget
download del file binario da 373 kB ha richiesto circa 5,7 secondi. Una velocità di circa 65 kB / se un po 'più di 512 kb / s.
In confronto, la soluzione cat di @ 131 termina in meno di 0,1 s, o quasi cento volte più velocemente. Non molto sorprendente, davvero.
Questo è ovviamente sciocco, poiché senza l'utilizzo di utility esterne, non c'è molto che possiamo fare con il file scaricato, nemmeno renderlo eseguibile.
gawk