0

I am trying to run a daemonised webserver as www-data user but I have reduced the problem down to the fact I can't even run the simplest of commands using su.

root@ubuntu:/var/www/hello# ls -la
total 8
drwxr-xr-x 2 www-data www-data 4096 Apr 22 11:39 .
drwxr-xr-x 8 www-data www-data 4096 Apr 22 11:38 ..
-rw-r--r-- 1 www-data www-data    0 Apr 22 11:39 hello.txt
root@ubuntu:/var/www/hello# sudo -u www-data 'ls'
hello.txt
root@ubuntu:/var/www/hello# su - www-data -c "ls"
root@ubuntu:/var/www/hello# echo $?  # Unknown problem as no error text to stout from previous command
1
root@ubuntu:/var/www/hello# su -c "ls" www-data
root@ubuntu:/var/www/hello# echo $?  # Unknown problem as no error text to stout from previous command
1
root@ubuntu:/var/www/hello# su -c "ls" root
hello.txt
root@ubuntu:/var/www/hello# su --help
Usage: su [options] [LOGIN]

Options:
  -c, --command COMMAND         pass COMMAND to the invoked shell
  -h, --help                    display this help message and exit
  -, -l, --login                make the shell a login shell
  -m, -p,
  --preserve-environment        do not reset environment variables, and
                                keep the same shell
  -s, --shell SHELL             use SHELL instead of the default in passwd

Two questions:

  1. How to get better error messages from su
  2. How to fix the fundamental problem of the command erroring when run as www-data user.
0

2 Answers 2

1

su runs the given command indirectly – it calls the target user's default shell (the 7th "login shell" field in /etc/passwd) with the -c, <command> parameters. For example, when you run su root -c "foo", it ends up running /bin/sh -c "foo" or similar.

However, service accounts (which aren't meant for interactive use) traditionally have a dummy shell configured, such as /bin/false or /sbin/nologin. (The former does nothing at all; the latter prints a message such as "This account is not available".)

(To find out what a user's default shell is, run getent passwd www-data and look at the last field.)

So in your case, su runs /bin/false -c "foo" or /sbin/nologin -c "foo", and nothing useful happens.

There is no error message because this behavior is not actually an error: su does precisely what it is configured to do, as does the so-called "shell" configured for this account. However, you can see more under-the-hood details by running strace -fe execve -- su www-data -c "foo" (you must be root to do this).


Actual services do not have this problem because they generally do not use the login-shell anywhere in the startup process. The service manager simply executes the daemon program directly. (In fact, you really should use a service manager. Most systems come with systemd, upstart, or at least 'start-stop-daemon'. su is not meant to run daemons at all.)

If you really must use su www-data to do something, then its --help output shows the necessary option:

-s, --shell SHELL             use SHELL instead of the default in passwd

Use this option to specify a "normal" shell, for example:

su www-data -s /bin/sh -c "foo"
0

When you use su, what is passed to the shell is the first argument after -c, not all arguments that follow it. So

su www-data -c ls foo

Executes ls and not ls foo. If you want to execute a command with arguments, include everything in quotes to make it a single argument:

su www-data -c "ls foo"

Then you will be executing ls with real arguments, and will see real messages.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .