4

I want to run this program as root. It activates a virtual environment and runs a python program in that virtual environment.

The program looks like this

$cat myfile.sh
source /pathto/venv/bin/activate
python /pathto/rsseater.py

If I just run it as root I get

$ sudo ./myfile.sh 
./myfile.sh: 2: ./myfile.sh: source: not found

I found this but if I try to add sudo -s to the top of the file it seems to change the prompt to a # -- but the python does not run as expected. I'm not sure what the program is doing when I have sudo -s at the top of the file like that.

How can I get this program to run as root?

bernie2436
  • 6,655

1 Answers1

6

You generally want to add a call to an interpreter at the top of your scripts, like so:

$cat myfile.sh
#!/bin/bash

source /pathto/venv/bin/activate
python /pathto/rsseater.py

This may seem very similar to what you have but is it in fact very different. In your scenario you're attempting to run the commands within the shell that get's invoked when you run sudo. With the example above, you're getting a separate Bash shell which will have the various commands after the #!/bin/bash line invoked within it. #!/bin/bash results in a new Bash shell getting forked.

Interpreters and shebang

The nomenclature of #! is called a shebang. You can read more about it through the various Q&A on this site and also on Wikipedia. But suffice to say, it tells the system that when a given file is "executed" (aka. run) to load a program from disk first (an interpreter), which then is tasked with the job of parsing the contents of the file you just executed.

NOTE: Essentially everything after the shebang line.

Interpreters

An interpreter is any program that can process commands one at a time from a file. In this case we're using the Bash shell as the interpreter. But there are other shells that you could use here too, such as C shell or Korne shell among others.

You can also use higher level interpreters such as Perl, Ruby, or Python too in this same manner.

Why the error using 'sudo -s'

If you take a look at the man page for sudo it has this to say about -s:

 -s [command]
            The -s (shell) option runs the shell specified by the SHELL 
            environment variable if it is set or the shell as specified in 
            the password database.  If a command is specified, it is passed
            to the shell for execution via the shell's -c option.  If no 
            command is specified, an interactive shell is executed.

So when you run this command:

$ sudo -s ./myfile.sh

The following happens:

$ /bin/sh
sh-4.2$ source somesource.bash 
sh: source: somesource.bash: file not found

The shell, /bin/sh does not support the command source.

slm
  • 369,824
  • ah. good to know. can you explain a little more about what an interpreter is? – bernie2436 Jul 10 '14 at 18:58
  • @akh2103 - see updates. – slm Jul 10 '14 at 19:04
  • many thanks. that is helpful. so when I added sudo -s to the top of the file it just changed the current bash terminal to root? (and then stopped trying to execute the file). just trying to understand why sudo -s did not work – bernie2436 Jul 10 '14 at 19:16
  • The error you're encountering tells me that whatever shell you're using couldn't find the command source. Without knowing particulars it's difficult to say why it couldn't find it. using sudo -s will spawn a shell based on either a env. var. ($SHELL) or a user's entry in /etc/passwd. I'm guessing that the root user has /bin/sh as their shell, which doesn't support the command source. – slm Jul 10 '14 at 19:27
  • 1
    @akh2103 - see above comment + edit. LMK if that makes sense. – slm Jul 10 '14 at 19:29
  • yes. that explains. I am assuming the SHELL variable is set to /bin/sh. – bernie2436 Jul 10 '14 at 19:36
  • @akh2103 - either that or /bin/sh since you're running via cron. – slm Jul 10 '14 at 19:40