# rc_run_command and command_interpreter



## Mr_Fix_It (Nov 17, 2011)

I'm trying to write a file to start and stop a python script. Here's what I've written.


```
#!/bin/sh
#
# PROVIDE: sabnzbd
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf
# to enable this service:
#
# sabnzbd_enable (bool):	Set to NO by default.
#			Set it to YES to enable it.
# sabnzbd_user:  The user account sabnzbd daemon runs as what
#			you want it to be. It uses '_sabnzbd' user by
#			default. Do not sets it as empty or it will run
#			as root.
# sabnzbd_dir:	Directory where sabnzbd lives.
#			Default: /usr/local/sabnzbd
# sabnzbd_pid:  The name of the pidfile to create.
#     Default is sabnzbd.pid in /var/run/sabnzbd/.

. /etc/rc.subr

name="sabnzbd"
rcvar=${name}_enable
load_rc_config ${name}


: ${sabnzbd_enable:="NO"}
: ${sabnzbd_user:="_sabnzbd"}
: ${sabnzbd_dir:="/usr/local/sabnzbd"}
: ${sabnzbd_pid:="/var/run/sabnzbd/sabnzbd.pid"}
: ${sabnzbd_conf_dir="${sabnzbd_dir}"}

command=${sabnzbd_dir}/SABnzbd.py
command_interpreter="/usr/bin/python"
command_args="-d -f ${sabnzbd_conf_dir}/sabnzbd.ini"
pidfile=${sabnzbd_pid}

run_rc_command "$1"
```

Problem is when I try to run this I get.



```
./sabnzbd.freenas: DEBUG: pid file (/var/run/sabnzbd/sabnzbd.pid): not readable.
./sabnzbd.freenas: DEBUG: checkyesno: sabnzbd_enable is set to YES.
Starting sabnzbd.
./sabnzbd.freenas: DEBUG: run_rc_command: doit: su -m sabnzbd -c 'sh -c "/mnt/Television/Applications/SABnzbd-0.6.10/SABnzbd.py  -d -f /mnt/Television/Applications/sabconfig/sabnzbd.ini"'
/mnt/Television/Applications/SABnzbd-0.6.10/SABnzbd.py: not found
./sabnzbd.freenas: WARNING: failed to start sabnzbd
```

Mainly I'm confused about the run_rc_command. This is su-ing to the user, and running a command. For some reason that command is the sh shell and passing the location of my script. It's odd that there is no call to python in there, though I set the command_interpreter variable. I would have thought it would attempt to call the script as a python script, rather than a sh script?.

Of course the file exists and I've chmod+x it.


```
ll /mnt/Television/Applications/SABnzbd-0.6.10/SABnzbd.py 
-rwxr-xr-x  1 sabnzbd  sabnzbd  60254 Oct 17 18:37 /mnt/Television/Applications/SABnzbd-0.6.10/SABnzbd.py*
```

Anyone have some pointers?


----------



## Mr_Fix_It (Nov 17, 2011)

Apparently the shebang was wrong. That error message doesn't really match up with that but hey.

It was


```
#!/usr/bin/python
```

It needed to be


```
#!/usr/local/bin/python
```

Not 100% sure why that matters that much, but now it gets past that section so yay.


----------



## DutchDaemon (Nov 17, 2011)

Well, it matters so much because Python is in /usr/local/bin, not /usr/bin .... Note that Python is _add-on software_ (a port / package) and as such will always end up under /usr/local/(s)bin. Only files belonging to the FreeBSD _base system_ will be found under /usr/(s)bin.


----------



## Mr_Fix_It (Nov 17, 2011)

Yeah that makes sense, but as a bit of a noob to the shebang thing, would there be a way of specifying it so it would work on different platforms? It seems the linux side is expecting /usr/bin/python, whereas (as you said, because of ports) FreeBSD wants /usr/bin/local/python, or am I always doomed to be re-writing the shebang to fix this?

Also,

Now that I'm able to start the program, it seems I need to add some extra folders into PATH. I've encountered a slight problem with it though.

I can run export PATH=/new/location:$PATH and that seems to work when the user is ommitted (e.g. it runs as root), however if I specify the user, which would give that *su -m sabnbzd* portion, the new path doesn't seem to go into the *su* command. This means the script can't find some binaries it needs.

How would I keep the ability to run as the user sabnzbd, with modifying the PATH variable? Is there a simple way to make it fall through the script, or where would I modify that user to use the different PATH settings?


----------



## SirDice (Nov 17, 2011)

Mr_Fix_It said:
			
		

> Yeah that makes sense, but as a bit of a noob to the shebang thing, would there be a way of specifying it so it would work on different platforms?. It seems the linux side is expecting /usr/bin/python, whereas (as you said, because of ports) freebsd wants /usr/bin/local/python, or am I always doomed to be re-writing the shebang to fix this?.


You could try this:

```
#!/usr/bin/env python
```



> Is there a simple way to make it fall through the script?, or where would I modify that user to use the different PATH settings.


Don't rely on PATH


----------



## Mr_Fix_It (Nov 18, 2011)

SirDice said:
			
		

> You could try this:
> 
> ```
> #!/usr/bin/env python
> ```



Ah you see that seems more platform independent and nice 



> Don't rely on PATH



Hmm okay, any suggestions as how to solve it? I'm running this on FreeNAS, so everything needs to sit on a different place than usual. I have the extra binaries on another hard-drive. Hence I thought I would use PATH to make sure the python script can find them.

What do you recommend instead of PATH? I'm also setting the PYTHONPATH variable too, but this seems to fall through *su -m*, whereas path gets reset.


----------



## SirDice (Nov 18, 2011)

Mr_Fix_It said:
			
		

> What do you recommend instead of PATH?


I've seen a lot of scripts do something like this:

```
PYTHON=`which python`
${PYTHON} /some/python/script.py
```


----------



## Mr_Fix_It (Nov 18, 2011)

Mhmm. Not really the problem I'm having though.

It finds python fine when run as the user, but the python script depends on binaries which aren't in path. 

I'm not 100% how command_interpreter works, or what it does to the command that's run. But I'm feeling maybe I have to make the script have


```
COMMAND= "export PATH=$PATH:/extrapath ; ${sabnzbd_dir}/SABnzbd.py"
```

Which is to be honest, gross. I was hoping there was a nicer way to deal with this.


----------



## SirDice (Nov 18, 2011)

Could you give some examples from your code? I'm not exactly sure where you have a problem, in python or in the shell.

If the needed binaries are in a different place when on different systems it's going to be tricky to come up with a solution that works everywhere.


----------



## Mr_Fix_It (Nov 19, 2011)

Yeah. I've thought about it more. You're correct in saying that PATH should be avoided at all costs in an init script.

I'm more thinking maybe, for the FreeNAS case, write a second script that will symlink them into the correct path on startup. This would mean a generic rc.d script would work.


----------

