Unix & Linux: How to download a file using just bash and nothing else (no curl, wget, perl, etc.)?
Channel: Roel Van de Paar
Date: 17/08/2020

Unix & Linux: How to download a file using just bash and nothing else (no curl, wget, perl, etc.)?


The Question: I have a minimal headless *nix which does not have any command line utilities
for downloading files (e.g. no curl, wget, etc). I only have bash.
How can I download a file?
Ideally, I would like a solution that would work across a wide range of *nix.

Solutions: Please watch the whole video to see all solutions, in order of how many people found them helpful

== This solution helped 67 people ==
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.1rnHost: ${HOST}rn${tag}rnrn" ＞&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: https://superuser.com/users/168962/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.

== This solution helped 20 people ==
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

== This solution helped 4 people ==
If you have this package libwww-perl
You can simply use:
/usr/bin/GET

With thanks & praise to God, and with thanks to the many people who have made this project possible! | Content (except music & images) licensed under cc by-sa 3.0 | Music: https://www.bensound.com/royalty-free-music | Images: https://stocksnap.io/license & others | With thanks to user zw963 (https://unix.stackexchange.com/users/148127), user Yecheng Fu (https://unix.stackexchange.com/users/206361), user woodstack (https://unix.stackexchange.com/users/43143), user tanius (https://unix.stackexchange.com/users/18163), user stackexchanger (https://unix.stackexchange.com/users/42522), user ilkkachu (https://unix.stackexchange.com/users/170373), user Chris Snow (https://unix.stackexchange.com/users/24554), user 131 (https://unix.stackexchange.com/users/84338), and the Stack Exchange Network (http://unix.stackexchange.com/questions/83926). Trademarks are property of their respective owners. Disclaimer: All information is provided "AS IS" without warranty of any kind. You are responsible for your own actions. Please contact me if anything is amiss at Roel D.OT VandePaar A.T gmail.com.