Skip to content

Instantly share code, notes, and snippets.

@schoettl
Created August 14, 2017 17:59
Show Gist options
  • Save schoettl/f73a16197e694231dcfd241cf94f12cb to your computer and use it in GitHub Desktop.
Save schoettl/f73a16197e694231dcfd241cf94f12cb to your computer and use it in GitHub Desktop.
Automatically change the /etc/hosts file depending on the network you are currently in
#!/bin/bash
# Change the hosts file /etc/hosts - must run as root.
# To be used with a cron job or systemd service to automatically
# adjust the hosts file depending on the network the computer is in.
printUsage() {
cat <<EOF
usage: $PROGNAME (-a | -n NETWORK) DOMAIN_NAME IP_ADDRESS
$PROGNAME -r DOMAIN_NAME
options:
-a
add an entry to the hosts file
-r
remove an entry from the hosts file
-n NETWORK
switch the entry in the hosts file depending on the current network the
computer is in. NETWORK must be the IPv4 broadcast address of the
network as printed in 'ip addr'. use -N to see the current networks.
-N
print networks to which this computer is currently connected
-h
print this help message
EOF
}
readonly PROGNAME=$(basename "$0")
# $1: error message
exitWithError() {
echo "$1" >&2
exit 1
}
# $*: command line arguments = "$@"
parseCommandLine() {
declare commandOptionCounter=0
while getopts 'harn:N' OPTION; do
case $OPTION in
h)
printUsage
exit 0
;;
a) declare -rg ADD_ENTRY=1
((commandOptionCounter++))
;;
r) declare -rg REMOVE_ENTRY=1
((commandOptionCounter++))
;;
n) declare -rg NETWORK=$OPTARG
((commandOptionCounter++))
;;
N) printNetworks
exit
;;
*) printUsage >&2
# prints usage after the default error message (invalid option or missing option argument).
# default error messages are disabled if the first character of optstring is ":".
exit 1
;;
esac
done
shift $((OPTIND-1))
(( commandOptionCounter == 1 )) \
|| exitWithError "error: you must provide exactly one command option (-a, -r, or -n)"
if (( $# != 2 )); then
printUsage
exit 1
fi
declare -gr DOMAIN_NAME=$1
declare -gr IP_ADDRESS=$2
[[ -n $ADD_ENTRY && -z $IP_ADDRESS ]] \
&& exitWithError "error: you must specify an IP address when using -a"
return 0
}
createBackupOnFirstRun() {
[[ -e /etc/hosts.orig ]] \
|| cp /etc/hosts /etc/hosts.orig
}
printNetworks() {
ip addr | awk '$1=="inet"{print $4}'
# ifconfig | awk '$1=="inet"{print $6}'
}
isInNetwork() {
printNetworks | grep --quiet "$NETWORK"
}
addEntry() {
if grep --quiet "$DOMAIN_NAME" /etc/hosts; then
echo "info: hosts file already contains entries for '$DOMAIN_NAME'"
else
echo "debug: adding entry to hosts file"
echo "$IP_ADDRESS $DOMAIN_NAME" >> /etc/hosts
fi
}
removeEntry() {
declare tmp
tmp=$(mktemp)
echo "debug: removing entry from hosts file"
grep -vF "$DOMAIN_NAME" /etc/hosts > "$tmp" && cp "$tmp" /etc/hosts
}
main() {
parseCommandLine "$@"
createBackupOnFirstRun
if [[ -n $NETWORK ]]; then
if isInNetwork; then
echo "debug: is in network"
addEntry
else
echo "debug: is not in network"
removeEntry
fi
elif [[ -n $REMOVE_ENTRY ]]; then
removeEntry
elif [[ -n $ADD_ENTRY ]]; then
addEntry
else
printUsage
fi
}
main "$@"
@schoettl
Copy link
Author

Example installation using a cronjob:

$ sudo crontab -e
*/3 * * * * /root/bin/change-hosts-file  -n 192.168.156.255  example.com 192.168.156.201
^D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment