Python3 CGI Script Execution on FreeBSD & Apache: env: python3: No such file or directory

My new Synology 218+ supports virtual machines, but with only 2 GB of RAM pre-installed, it only left ~200 MB available. This isn’t enough for any newish version of Linux, but it is adequate for a very basic FreeBSD Apache web server. I was able to create the VM and install Apache, python3, and several python libraries no problem, but to issues trying to get Python CGI scripts working. I had already enabled CGI by creating the file /usr/local/etc/apache24/Includes/cgi.conf and restarting Apache:

LoadModule cgi_module libexec/apache24/mod_cgi.so

<Directory "/usr/local/www/apache24/cgi-bin">
    AllowOverride None
    Options +ExecCGI
    AddHandler cgi-script .cgi
    Require all granted
</Directory>

Then created a very simple Python3 CGI script:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
print("Status: 200\nContent-Type: text/plain; charset=UTF-8\n")
print("PATH =", os.environ['PATH'])

The 500 error would show up in the apache logs like this:

[Tue Sep 01 11:45:45.476977 2020] [cgi:error] [pid 1126] [client 192.168.1.100:47820] AH01215: env: python3: No such file or directory: /usr/local/www/apache24/cgi-bin/python3.cgi
[Tue Sep 01 11:45:45.477145 2020] [cgi:error] [pid 1126] [client 192.168.249.197:47820] End of script output before headers: python3.cgi

Almost seems like the ‘env’ was the problem. Yet running from CLI, it operated fine:

root@:/usr/local/www/apache24/cgi-bin # ./python3.cgi 
Status: 200
Content-Type: text/plain; charset=UTF-8

PATH = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin

In desperation, I tried changing the first line to explicitly reference the python3 binary’s location:

#!/usr/local/bin/python3

The script then started returning 200s, and showed the problem: the PATH only contained /bin and /usr/bin, but, on FreeBSD, python3 is installed in /usr/local/bin since it’s installed via package:

root@:/usr/local/www/apache24/cgi-bin # whereis python3
python3: /usr/local/bin/python3 /usr/ports/lang/python3

I didn’t want to change the first line of all my CGI scripts and cause them to break in Linux. So the better fix was tell Apache to look in /usr/local/bin as part of the path by adding this line to any of the config files:

SetEnv PATH /bin:/usr/bin:/usr/local/bin

I did not see any need to have /sbin, /usr/sbin, or /usr/local/sbin in the path since there are no valid interpreters in these paths. But having them in there doesn’t hurt anything.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s