1

I have a python script which I want to start using a rc(8) script in FreeBSD. The python script uses the #!/usr/bin/env python2 pattern for portability purposes. (Different *nix's put interpreter binaries in different locations on the filesystem).

The FreeBSD rc scripts will not work with this.

Here is a script that sets up a test scenario that demonstrates this:

#!/bin/sh

# Create dummy python script which uses env for shebang.
cat << EOF > /usr/local/bin/foo
#!/usr/bin/env python2.7
print("Hello foo")
EOF

# turn on executable bit
chmod +x /usr/local/bin/foo

# create FreeBSD rc script with command_interpreter specified.
cat << EOF > /usr/local/etc/rc.d/foo
#!/bin/sh
#
# PROVIDE: foo

. /etc/rc.subr

name="foo"
rcvar=foo_enable
command_interpreter="/usr/local/bin/python2.7"
command="/usr/local/bin/foo"

load_rc_config \$name
run_rc_command \$1
EOF

# turn on executable bit
chmod +x /usr/local/etc/rc.d/foo

# enable foo
echo "foo_enable=\"YES\"" >> /etc/rc.conf

Here follows a console log demonstrating the behaviour when executing the rc script directly. Note this works, but emits a warning.

# /usr/local/etc/rc.d/foo start
/usr/local/etc/rc.d/foo: WARNING: $command_interpreter /usr/local/bin/python2 != python2
Starting foo.
Hello foo
#

Here follows a console log demonstrating the behaviour when executing the rc script using the service(8) command. This fails completely.

# service foo start
/usr/local/etc/rc.d/foo: WARNING: $command_interpreter /usr/local/bin/python2 != python2
Starting foo.
env: python2: No such file or directory
/usr/local/etc/rc.d/foo: WARNING: failed to start foo
#

Why does the service foo start fail?

Why does rc warn about the interpreter? Why does it not use the interpreter as specified in the command_interpreter variable?

Jev Björsell
  • 891
  • 1
  • 9
  • 25

2 Answers2

1

Self answered my question, but I'm hoping someone else will give a better answer for posterity

The reason why env(1) does not work is because it expects an environment in the first place, but rc scripts run before the environment is set up. Hence it fails. It seems that the popular env shebang pattern is actually an anti-pattern.

I do not have a cogent answer for the command_interpreter warning.

Jev Björsell
  • 891
  • 1
  • 9
  • 25
  • 1
    Does the `ps`/etc. output for your script say `python` or `/usr/local/bin/python2`? I'm betting it says `python` and that mismatch is the cause of the `command_interpreter` warning. But that's entirely a wild guess. – Etan Reisner Jul 17 '15 at 19:58
  • I had the same error message as the op. @EtanReisner guess was spot on. My interpreter was "/usr/local/bin/python" but the shebang line in my script was "/usr/bin/env python" and that triggered the warning. – Jagu Sep 22 '19 at 07:10
0

The command interpreter warning is generated by the _find_processes() function in /usr/src/etc/rc.subr.

The reason that it does that is because a service written in an interpreted language is found in ps output by the name of the interpreter.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94