Friday, July 7, 2017

The PATH of cron

Short version

Postgres Plus keeps psql out /usr/bin, so you need to set PATH in your cron jobs (including for WAL-E).

Longer version

Like all good people, I set up a cron jobs to run nightly WAL-E base backups. With one client, this failed the first time:
wal_e.main ERROR MSG: could not run one or more external programs WAL-E depends upon DETAIL: Could not run the following programs, are they installed? psql STRUCTURED: time=2017-07-07T03:00:01.957961-00 pid=25833
Turns out they were using Postgres Plus, and it puts psql in /opt/PostgresPlus/9.3AS/bin. That directory is in the enterprisedb user's PATH, of course, but not in the minimal PATH that cron jobs get by default. So I had to log in as enterprisedb, echo $PATH, and then paste PATH = [what echo said] at the top of my cron job. Moral of the story: take care when setting up cron jobs for PostgreSQL forks, or for non-standard community PostgreSQL installations.


  1. Hi,

    FWIW, RPM installations create symlinks of multiple binaries under /usr/bin.

  2. The community source install doesn't put any binaries in /usr/bin, so it is hard to say the Postgres Plus behavior is non-standard. I wasn't even aware that some installs put symlinks in /usr/bin, but Devrim would know. I thought they just modified PATH.

    I think Debian packages do something similar, and frankly it is a pain. I have to uninstall it so it doesn't interfere with my source install.

  3. Both Debian-style and Red Hat–style PGDG packages do put psql in /usr/bin. It's just not a binary. ;) I've given the implementation details below, but all I really care about is being able to call psql without an absolute path. Using cron to run psql (or other PostgreSQL binaries, like vacuumdb) seems like a common enough use case that it's worth supporting.

    Here's how it works currently:

    PGDG RPMs uses the Red Hat /etc/alternatives system, so /usr/bin/psql is a symlink to /etc/alternatives/pgsql-psql, which in turn is a symlink to the version-specific psql binary (I *think* by default it always points to the installed psql with the highest version number).

    PGDG debs make install a Perl wrapper as /usr/bin/psql. By passing arguments, you can select the specific version of psql you want (I've never done this) — or, if you pass no arguments, the script is just a pass-through to the installed psql binary with the highest version number.