how to download a file using just bash and nothing else (no curl, wget, perl, etc.)
If you have bash 2.04 or above with the /dev/tcp
pseudo-device enabled, you can download a file from bash itself.
Paste the following code directly into a bash shell (you don't need to save the code into a file for executing):
function __wget() {
: ${DEBUG:=0}
local URL=$1
local tag="Connection: close"
local mark=0
if [ -z "${URL}" ]; then
printf "Usage: %s \"URL\" [e.g.: %s http://www.google.com/]" \
"${FUNCNAME[0]}" "${FUNCNAME[0]}"
return 1;
fi
read proto server path <<<$(echo ${URL//// })
DOC=/${path// //}
HOST=${server//:*}
PORT=${server//*:}
[[ x"${HOST}" == x"${PORT}" ]] && PORT=80
[[ $DEBUG -eq 1 ]] && echo "HOST=$HOST"
[[ $DEBUG -eq 1 ]] && echo "PORT=$PORT"
[[ $DEBUG -eq 1 ]] && echo "DOC =$DOC"
exec 3<>/dev/tcp/${HOST}/$PORT
echo -en "GET ${DOC} HTTP/1.1\r\nHost: ${HOST}\r\n${tag}\r\n\r\n" >&3
while read line; do
[[ $mark -eq 1 ]] && echo $line
if [[ "${line}" =~ "${tag}" ]]; then
mark=1
fi
done <&3
exec 3>&-
}
Then you can execute it as from the shell as follows:
__wget http://example.iana.org/
Source: Moreaki's answer upgrading and installing packages through the cygwin command line?
Update: as mentioned in the comment, the approach outlined above is simplistic:
- the
read
will trashes backslashes and leading whitespace. - Bash can't deal with NUL bytes very nicely so binary files are out.
- unquoted
$line
will glob.
Use lynx.
It is pretty common for most of Unix/Linux.
lynx -dump http://www.google.com
-dump: dump the first file to stdout and exit
man lynx
Or netcat:
/usr/bin/printf 'GET / \n' | nc www.google.com 80
Or telnet:
(echo 'GET /'; echo ""; sleep 1; ) | telnet www.google.com 80
Adapted from Chris Snow answer This can also handle binary transfer files
function __curl() {
read proto server path <<<$(echo ${1//// })
DOC=/${path// //}
HOST=${server//:*}
PORT=${server//*:}
[[ x"${HOST}" == x"${PORT}" ]] && PORT=80
exec 3<>/dev/tcp/${HOST}/$PORT
echo -en "GET ${DOC} HTTP/1.0\r\nHost: ${HOST}\r\n\r\n" >&3
(while read line; do
[[ "$line" == $'\r' ]] && break
done && cat) <&3
exec 3>&-
}
- i break && cat to get out of read
- i use http 1.0 so there's no need to wait for/send a connection:close
You can test binary files like this
ivs@acsfrlt-j8shv32:/mnt/r $ __curl http://www.google.com/favicon.ico > mine.ico
ivs@acsfrlt-j8shv32:/mnt/r $ curl http://www.google.com/favicon.ico > theirs.ico
ivs@acsfrlt-j8shv32:/mnt/r $ md5sum mine.ico theirs.ico
f3418a443e7d841097c714d69ec4bcb8 mine.ico
f3418a443e7d841097c714d69ec4bcb8 theirs.ico