Brain Phrye

code cooking diy fiction personal photos politics reviews tools 


[ Listen to article ]

The Laravel PHP framework uses environment variables to configure itself. There are ways to set envirnment variables for Apache but then you also need to set them for cron and for CLI scripts as well.

On Ubuntu this is usually done with /etc/environment which is read by the pam_env PAM module when a PAM session is created. I wanted this to work on FreeBSD which was a bit of a learning experience into where free unixes are diverging.

The first is that Linux systems usually use linux-pam while FreeBSD uses openpam. The second is that openpam lacks a pam_env.

That seemed simple enough to fix so I wrote a simple one that had was less features than the linux-pam one but did inject the contents of /etc/environment into a session’s environment. And it worked.

Well. It worked for everything except cron.

In that case it turns out that FreeBSD forked a while back from Vixie cron and while they use PAM for auth, they don’t use it to create a session. Sigh.

So what does this have to do with shebang lines?

Well, my next way to solve this was to make a shell wrapper to php that would use apache’s method of reading in shell vars (the envvars file that is sourced by the init script). Then all cron/CLI apache scripts could just use #!/usr/local/bin/phpcli as their shebang line.

The shebang #! is a cute unix hack to signal to the kernel that it should use the given file to actually execute argv[0]. See [execve(2)] for more info.

Except that manpage lacks the full story. For that, it’s more useful to read about the history of the shebang line. Specifically the section explaining why you can’t nest interpreters except on Linux or Minix.

I could write a thin C wrapper around my shell wrapper, but I decided I’d gone down enough rabbit holes and am just running the script directly.

Still, an interesting tour around the history of unix and how even still the implementations don’t fully line up in odd little ways.