Created
August 14, 2017 17:59
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example installation using a cronjob: