OS X Network Location Support From The Command Line
I move between three different network configurations with my powerbook in an average day. Two of these configurations have proxy servers and one does not. Mac OS X has really excellent network location support that lets me configure this stuff once so that switching locations is as simple as invoking QuickSilver, typing the first few letters of the network location and BAM.
Most applications automatically pick up the new proxy configuration
but some do not, like Firefox (which is one of three big reasons I
still use Safari). I do a lot of work from the command line with network
based tools such as curl
, wget
, port
, http_ping
, links
, svn
,
etc. None of these use the system proxy settings but most support
specifying a proxy server via the http_proxy
environment
variable.
I’ve searched high and low for a mechanism that would handle setting the
http_proxy
variable based on my current network location but have come
up with nothing.
First, you need to create a file /etc/http_proxy
that specifies the
proxy servers for each Network Location you have setup in your Network
Preferences (If anyone can figure out how to get the proxy information
directly please let me know. I can get the current network location but
not information about it). The file might look something like this:
Work = http://proxy.example.com:80
Library = http://proxy.library.com:80
The keys are the names of your network locations and the values are in
http://proxy-host:proxy-port
form.
Next, you’ll need to put the following script somewhere along your
$PATH
named proxy-config
and give it a chmod +x
too.
#!/bin/bash
# source this into your current to have the proxy
# environment variables needed by many command line
# apps setup correctly.
# get the current network location name
netloc=$(/usr/sbin/scselect 2>&1 | egrep '^ \* ' | \
sed 's:.*(\(.*\)):\1:')
# find the proxy in /etc/http_proxy based on the
# current location
http_proxy=$(egrep "$netloc[ \t]*=" /etc/http_proxy | \
sed 's/.*=[ \t]*\(.*\)/\1/')
if [ -n "$http_proxy" ]; then
export http_proxy
export HTTP_PROXY="$http_proxy"
else
unset http_proxy
unset HTTP_PROXY
fi
# the rest of this is used for symlink commands
bn=$(basename $0)
if [ "$bn" != "proxy-config" ]; then
dn=$(cd $(dirname $0); pwd)
for p in $(echo $PATH | sed 's/:/ /g'); do
[ "$p" != "$dn" ] && [ -x "$p/$bn" ] && exec "$p/$bn" "$@"
done
fi
This script has two usage scenarios. You can source this into your
current shell to have the http_proxy
set correctly based on your
current network location:
$ . proxy-config
$ echo $http_proxy
http://proxy.example.com:80
Alternatively, you can create symlinks to the proxy-config
script
using the names of commands that require http_proxy
and the script
will automatically set the variable and exec the real command.
Got that? No? Okay, let’s move on.
Pretend you have /usr/bin/curl
and you put the script from above at
/usr/local/bin/proxy-config
. You can get curl
to use the approriate
proxy settings by doing something like this:
# mkdir /usr/local/proxybin
# cd /usr/local/proxybin
# ln -s ../bin/proxy-config curl
# ls -l
total 4
lrwxr-xr-x 1 root wheel 19 May 11 13:30 curl -> ../bin/proxy-config
As long as /usr/local/proxybin
is on your $PATH
before /usr/bin
,
executing curl
will actuall call proxy-config
. proxy-config
will
then setup the proxy settings and exec /usr/bin/curl
.
Now just create a symlink just like the one made for curl
for anything
else that requires proxy settings and enjoy network location support
from the command line.