Networking#
Bash itself doesn’t speak the network, it orchestrates programs that do. The toolkit is mostly coreutils plus a handful of well-known network utilities.
HTTP#
$ curl -fsSL https://example.com/
$ curl -I https://example.com/
$ curl -X POST -H 'content-type: application/json' \
-d '{"a":1}' https://api.example.com/v1/items
$ curl -fsS --retry 3 --retry-connrefused -o file.tgz \
https://example.com/file.tgz
$ wget -q -O- https://example.com/
$ wget -nc https://example.com/file.tgz
Common flags worth memorizing:
-f(curl), fail on HTTP errors. Use everywhere; without it scripts silently miss 4xx/5xx.-s, silent. Often paired with-Sto keep error messages.-L, follow redirects.--max-time,--connect-timeout, always set both in scripts.
JSON#
$ curl -fsS https://api.example.com/users/1 | jq '.name'
$ jq -r '.items[].id' input.json
$ curl -fsS -X POST https://api.example.com/items \
--data-raw "$(jq -n --arg n "$NAME" '{name:$n}')"
TCP / UDP#
Bash has built-in /dev/tcp and /dev/udp pseudo-paths, handy for
probes when nc isn’t available:
$ if (echo > /dev/tcp/host/22) 2>/dev/null; then
$ echo "open"
$ fi
$ exec 3<>/dev/tcp/example.com/80
$ printf 'GET / HTTP/1.0\r\nHost: example.com\r\n\r\n' >&3
$ cat <&3
$ exec 3<&-
For real interactive work, use netcat:
$ nc -zv host 22
$ nc -u -zv host 53
$ nc -l -p 4444
DNS#
$ getent hosts example.com
$ dig +short example.com
$ dig +short example.com AAAA
$ dig @8.8.8.8 example.com
$ host example.com
SSH and File Transfer#
$ ssh user@host 'systemctl status nginx'
$ scp file user@host:/path/
$ rsync -aP src/ user@host:/path/
$ rsync -aP --delete src/ user@host:/path/
Authentication Tokens#
Don’t put tokens on the command line; they leak through ps, history, and
logs.
$ curl -H "Authorization: Bearer $(cat ~/.config/myapp/token)" ...
$ curl -H "Authorization: Bearer $TOKEN" ...
$ curl --netrc-file ~/.netrc ...
Diagnostics#
$ ping -c 3 host
$ traceroute host
$ mtr host
$ ss -tulpn
$ tcpdump -ni any port 443
$ tshark -i any -f 'port 443'
For “is this URL up and what does it look like”:
$ curl -o /dev/null -s -w 'http=%{http_code} time=%{time_total}\n' https://example.com/