Following on from this post, you probably have multiple versions of PostgreSQL installed on your Mac. In that post, I added an example function to help you manage all these concurrent installs. Today, I’m back with a full-fledged shell script to help manage all this. Without further ado, the script:
#!/bin/zsh
wanted_ver=$1
no_restart=
# is the version requested installed?
brew ls --version postgresql@${wanted_ver} &>/dev/null
if [[ $? -eq 0 ]] ; then
# yes, carry on
:
else
# nope, so install it
echo "Installing PostgreSQL ${wanted_ver}... "
brew install petere/postgresql/postgresql@${wanted_ver}
fi
# is postgresql is running?
for i in /usr/local/var/postgres/*
do
check_ver=$(basename ${i})
is_running=$(ps -few|egrep -- "[p]ostgres.*-D.*${check_ver}")
if [[ -z ${is_running} ]] ; then
# nope, carry on
:
else
# it is. is it the requested version?
if [[ "${wanted_ver}" = "${check_ver}" ]] ; then
# yup, carry on
no_restart=t
else
# nope, so kill it
echo -n "Stopping PostgreSQL ${check_ver}... "
/usr/local/opt/postgresql@${check_ver}/bin/pg_ctl \
-D /usr/local/var/postgres/${check_ver} \
stop -w -mf | grep 'stopped'
fi
fi
done
# what version is active?
if [[ -e /usr/local/bin/psql ]] ; then
active_ver=$(/usr/bin/stat -f %Y /usr/local/bin/psql | cut -d\/ -f3 | cut -d\- -f2 | cut -d\@ -f2)
else
active_ver=0
fi
# is the active version the requested version?
if [[ "${active_ver}" = "${wanted_ver}" ]] ; then
# yup, carry on
:
else
# nope, so deactivate it
echo -n "Deactivating PostgreSQL ${active_ver}... "
brew unlink --force --overwrite postgresql@${active_ver} | cut -d\ -f3-
# and activate the correct version
echo -n "Activating PostgreSQL ${wanted_ver}... "
brew link --force --overwrite postgresql@${wanted_ver} | grep 'created' | cut -d\ -f3-
fi
# point to the correct data dir and port
PGDATA=/usr/local/var/postgres/${wanted_ver}
PGPORT="54$(echo ${wanted_ver} | tr -d .)"
# should we be starting a cluster?
if [[ "${no_restart}" = "t" ]] ; then
# nope, carry on
:
else
# yup. has the cluster been initialized?
if [[ ! -d ${PGDATA} ]] ; then
# nope, so let's do that
echo "Initializing PostgreSQL ${wanted_ver} cluster... "
initdb -k ${PGDATA} || initdb ${PGDATA}
echo "port = ${PGPORT}" >> ${PGDATA}/postgresql.conf
echo "log_destination = 'stderr'" >> ${PGDATA}/postgresql.conf
echo "logging_collector = on" >> ${PGDATA}/postgresql.conf
echo "log_filename = 'postgresql-%a.log'" >> ${PGDATA}/postgresql.conf
echo "log_truncate_on_rotation = on" >> ${PGDATA}/postgresql.conf
echo "log_rotation_age = 1d" >> ${PGDATA}/postgresql.conf
echo "log_rotation_size = 0" >> ${PGDATA}/postgresql.conf
echo "log_timezone = 'US/Michigan'" >> ${PGDATA}/postgresql.conf
echo "log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '" >> ${PGDATA}/postgresql.conf
else
# yup, carry on
:
fi
# start the cluster
echo -n "Starting PostgreSQL ${wanted_ver}... "
pg_ctl -D ${PGDATA} start > /tmp/pg.start 2>&1
grep 'server start' /tmp/pg.start
if [[ -x /usr/local/bin/pg_isready ]] ; then
ret=1
while [[ ${ret} -eq 1 ]]
do
# wait for the cluster to be available before exiting
pg_isready -q
ret=$?
done
fi
fi
echo "export PGDATA=${PGDATA}"
echo "export PGPORT=${PGPORT}"
But what does it do? It’s pretty simple actually. When you call this script, you tell it what version of PostgreSQL you want:
$ pg 9.6
and then the script does the following:
initdb
for the requested version if neededI’ll be the first to admit that the script could use additional work, but it’s functional enough to start using today. As I continue to improve the script, I’ll update the"post"with those changes, so check back every so often.
Enjoy.