I have a script that is executed by php so it runs as the www-data user. The script is pretty simple, it basically copies some pre-made files such as the hosts and interfaces files to the correct directories. Maybe update some permissions etc.

I thought creating a new user and giving that access to the required commands only through visudo might work but

  1. that still requests the user executing the .sh for a password and
  2. it plainly does not give the test user permissions.

visudo (all permission denied when running ./script.sh)

test ALL=(ALL) NOPASSWD:/bin/cp,/bin/mv,/bin/nano,/bin/chown,/bin/mv

When I change the test user to the actual user I'm logged in with, it works.

.sh executed by the logged in/www-data user trying to execute the commands as a different user with the required permissions.

sudo -H -u test cp test.txt /etc/test.txt
sudo -H -u test chown test /etc/test.txt
echo "ok"

What is the best way to enable the www-data user to execute a script that requires root permissions?

  • I'm not quite sure I understood you, but if you want to run a script whose internals require sudo to execute, wouldn't this work ? --- $ sudo bash -c "./script.sh [arg1[ arg2]]" where arg1, arg2 are optional script arguments. You may want to add the optional sudo flags: -E to preserve the user's environment variables, -u test to specify that user test runs the command. Just make sure that test is part of the sudo group and that your script is executable. If this suits you,there is no need to modify your sudoers file in a way that makes your system vunerable to attacks.
    – Cbhihe
    Jun 2, 2020 at 2:39
  • In fact, there is never a need to make your system vulnerable to attack ... unless you are building a honey pot of course.
    – Cbhihe
    Jun 2, 2020 at 2:45

1 Answer 1


The sudoers part you have shown does not make sense.

test ALL=(ALL) NOPASSWD:/bin/cp,/bin/mv,/bin/nano,/bin/chown,/bin/mv

You want just one of these lines, probably the last one.

Executing echo "ok" with no respect to the exit code of the earlier commands doesn't make much sense either.

As far as you have shown there are no sudo permissions for the user www-data.

On a normal system sudo -H -u test cp test.txt /etc/test.txt doesn't make sense because the user test cannot create files in /etc. This would only work if the target file exists and has write permissions for the user `test.

However, sudo -H -u test chown test /etc/test.txt never makes sense because the only user which can call chown that way successfully is root.


I guess what you need is this. A script


cp ~test/test.txt /etc/test.txt &&
    chown test /etc/test.txt    &&
    echo 'ok' || echo 'failure'
  1. Put that script in a path that is writable only by root
  2. Create a sudo permission like this

    www-data ALL= NOPASSWD:/path/to/script.sh
  3. Call the script as www-data like

    sudo /path/to/script.sh
  • Apologies for the unclear explanation. My script will be called from php exec. I figured out sudo needs to be in that command for things to work. Combined with your recommendations my script now appears to run. Am I correct thinking that every command inside script.sh will be executed as root? I've set chown root:root script.sh and chmod 755 script.sh, will this make things reasonably secure?
    – sjaak
    Jun 2, 2020 at 4:41
  • yes, all commands in script.sh will be executed as root. Your chown and chmod look good. Please accept the answer if it answers your question.
    – ruud
    Jun 2, 2020 at 9:00
  • @sjaak The script itself is not dangerous; it could even be allowed for every user to execute (as root). It does not contain confidential information. Thus it is not a problem that it is world-readable. It is rather useless, though, to make it world-executable as it would not work anyway. So no problem but as a general rule it may make sense to make sudo scripts readable for root (and admin groups) only. Jun 2, 2020 at 9:29

You must log in to answer this question.

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