I would like to run a bash script without opening a terminal in my Ubuntu system. Some other users will have to daily check and run that process. So I thought I could build a simple php website that could run the script. After some reading here at Stack Overflow and googleing I thought shell_exec could do the trick. But as I don't want to give permissions in some directories to www-data I want to run the scripts as the owner, user meteo.
This is my php:
$autput = shell_exec('date +%d/%m/%Y-%H:%m');
echo "<pre>Hora de inicio: $autput</pre>";
$output = shell_exec('/home/meteo/RAMS/SCRIPTS/RAMS_operatiu.bash');
echo "<pre>".$output."</pre>";
The content of sudoers file, sudo visudo
meteo ALL = NOPASSWD: /home/meteo/RAMS/SCRIPTS/RAMS_operatiu.bash
www-data ALL = NOPASSWD: /home/meteo/RAMS/SCRIPTS/RAMS_operatiu.bash
This way, www-data user runs my script (RAMS_operatiu.bash) but as this script runs an mpich job it has to check mpd.conf then the script crashes as there is not such file for www-data. It actually exists for meteo. So I would like to run as meteo better than www-data. I tried to use
$output = shell_exec('sudo -u meteo /home/meteo/www/RAMS/inicio_RAMS.sh');
but can't find the point to tell the php script to run as meteo, not www-data. Is this possible? Probably I am missing something.
Thank you very much for your help.
Related
I want PHP to execute a Python3 script.
I have done
$command = escapeshellcmd('pathtofile.py');
$output = shell_exec($command);
echo $output;
But whenever the script is run, I get an error :Permission Denied.
I'm running a web server (Apache2 on Ubuntu 18.04) and the VPS has only one user- root.
I have also donechmod +x path.py and added the shebang line in the scipt.
Basically, the script is run when a user successfully registers.
You must to add apache user in sudoers file like:
www-data ALL=(ALL:ALL) NOPASSWD:ALL
then you can execute script like this:
'sudo pathtofile.py'
Or you can use compiled wrapper.
Write C program, that executes script, than compile it. Than set sticky bit:
chown root:root wrapper
chmod a+rs wrapper
Than include www-data in the root group.
Now can execute wrapper from your php script, and wrapper will execute python script as root.
I've been unable to run php scripts that I need to use to start and stop webcam services that run on the local machine with the scripts. I can find nothing in the logs to indicate why the script doesn't' work.
I confess to being severely handicapped regarding PHP, especially server-side scripting.
The environment is Debian Jesse running Nginx with all required SSH and PHP modules installed
I have added www-data to the sudoers file with:
www-data ALL=(ALL) NOPASSWD: /var/www/html/start_webcam.sh
Enabled the $PATH environment for www-data at:
/etc/php5/fpm/pool.d/www.conf
The shell script resides in the .../html directory and runs from the terminal with no issues.
This is the code for both the php and shell scripts:
start_webcam.php:
<?php
echo exec('sudo bash /var/www/html/aspirebox/start_webcam.sh 2>&1, $output');
print_r($output);
?>
The $output and print_r stuff is there because it was the last thing I tried based on a post I found out here somewhere.
start_webcam.sh
#!/bin/bash
service motion start
Thanks in advance to anyone out here that has a clue. After 2 days of wrestling with this, I am sure that I do not.
according to Passing Variables to shell_exec()? you should change your code like this:
<?php
$output = exec('/var/www/html/aspirebox/start_webcam.sh 2>&1 ');
print_r($output);
?>
and let your bash script execute as all (no need to sudo bash):
chmod a+x /var/www/html/aspirebox/start_webcam.sh
Thank you very much - that worked.
I worked through getting the path straight for the directory the shell script runs in, and the correct path to run "service".
All I have now is to figure out why I'm getting "Failed to start motion.service: Access denied"
I've given www-data permission to run the script without a password on sudoers, have to keep digging.
Thanks again!
I have set of linux system commands that requires to be logged into shell first.
How can i do that in php ?
For example:
$output2 = shell_exec('ls -lrt /opt/test 2>&1');
Since /opt/test can be accessed by user/owner XXX only, I need to login with that username.
runuser command could be helpful but i need directions.
Actually I need to run an application via system command but before that user must be logged in to have access to that application.
One way to do it would be to create a shell script containing all of the commands that you need to run as the privileged logged in user, and then run that shell script using sudo.
You will need to change your sudoers file so that the execution of the script can be run by the user that the script is running as.
eg:
Cmnd_Alias HTTP_COMMANDS = /usr/local/my_ls_script
XXXX ALL=(ALL) NOPASSWD: HTTP_COMMANDS
Be careful when doing this though! Make sure that the sudoers line can only run the commands that you specify.
Also, make sure that you switch to the user at least once, and run sudo, otherwise, the webserver will not be able to run sudo for the user.
Additionally, you might need to disable NO_TTY in the sudoers file.
You would change your command to:
$output2 = shell_exec('sudo -u XXXX /usr/local/my_ls_script 2>&1');
I am running Apache on my localhost. From a PHP script run as www-user I would like to control Rhythmbox playback on my machine. So far I have a simple command in my PHP script:
exec('rhythmbox-client --pause');
This works great when I run it from the command-line as me, but if it runs as www-user I guess rhythmbox-client doesn't know/can't access my instance of Rhythmbox.
Is there an easy way for that PHP script to run as my user rather than www-user, or to tell rhythmbox-client which instance to control?
The overall application is that when my phone goes off-hook it calls my PHP script which pauses music, and resumes playback when the phone is on-hook. I love VoIP phones!
Solution:
Thanks to Carpetsmoker and Tarek I used sudo as the answer but there was a couple of problems. To overcome them I did the following:
Created a bash script to call rhythmbox-client. This bash script was executed using sudo in PHP as described in the answer below. Unfortunately rhythmbox-client didn't know what environment to control, so the bash script looks like this:
#! /bin/bash
DBUS_ADDRESS=`grep -z DBUS_SESSION_BUS_ADDRESS /proc/*/environ 2> /dev/null| sed 's/DBUS/\nDBUS/g' | tail -n 1`
if [ "x$DBUS_ADDRESS" != "x" ]; then
export $DBUS_ADDRESS
/usr/bin/rhythmbox-client --pause
fi
Now that bash script can be executed by PHP and wwwuser, and my phone can pause/play my music!
One solution is using sudo(8):
exec('sudo -u myuser ls /');
You will, obviously, need to setup sudo(8) to allow the user running your webserver to invoke it. Editing the sudoers file with visudo(8), you can use something like:
wwwuser ALL=/usr/bin/rhythmbox-client
To prevent Apache from being able to run other commands and only the rythymbox command.
In my case, the solution came this way:
Added this lines to sudoers file:
myuser ALL=(ALL) NOPASSWD: /usr/bin/prlctl
_www ALL=(ALL) NOPASSWD: /usr/bin/prlctl # IMPORTANT!!!
The EXEC() command in PHP was changed to:
exec("sudo -u myuser prlctl list -a", $out, $r);
If a process can be run by any user it can be run by PHP. Example is fortune command
-rwxr-xr-x 1 root root 18816 Oct 1 2009 /usr/games/fortune
Look at the x permission for every user. But this some times doesn't at all work and you may have to let the user, www-data or apache etc, run the program. You can sudo www-data and try to run the command. If it works then Apache/PHP should be able to run it.
I have a script in /var/www/myscript.sh which creates folders and runs the command svn update for my projects. I need to execute this script by calling it in a PHP file in the browser (i.e. Localhost/test.php). I tried using functions shell_exec() and exec() but those did not work. I ran my shell script in terminal with su www-data && ./myscript.sh and it worked. What else am I missing?
<?php
$output = shell_exec("./myscript.sh");
?>
Update 5/4/2011:
I added www-data ALL=(ALL) NOPASSWD:ALL to /etc/sudoers and it works, but this is very insecure. Is there another way to do this?
Several possibilities:
You have safe mode enabled. That way, only exec() is working, and then only on executables in safe_mode_exec_dir
exec and shell_exec are disabled in php.ini
The path to the executable is wrong. If the script is in the same directory as the php file, try exec(dirname(__FILE__) . '/myscript.sh');
You might have disabled the exec privileges, most of the LAMP packages have those disabled. Check your php.ini for this line:
disable_functions = exec
And remove the exec, shell_exec entries if there are there.
Good Luck!
Residuum did provide a correct answer to how you should get shell exec to find your script, but in regards to security, there are a couple of points.
I would imagine you don't want your shell script to be in your web root, as it would be visible to anyone with web access to your server.
I would recommend moving the shell script to outside of the webroot
<?php
$tempFolder = '/tmp';
$webRootFolder = '/var/www';
$scriptName = 'myscript.sh';
$moveCommand = "mv $webRootFolder/$scriptName $tempFolder/$scriptName";
$output = shell_exec($moveCommand);
?>
In regards to the:
i added www-data ALL=(ALL) NOPASSWD:ALL to /etc/sudoers works
You can modify this to only cover the specific commands in your script which require sudo. Otherwise, if none of the commands in your sh script require sudo to execute, you don't need to do this at all anyway.
Try running the script as the apache user (use the su command to switch to the apache user) and if you are not prompted for sudo or given permission denied, etc, it'll be fine.
ie:
sudo su apache (or www-data)
cd /var/www
sh ./myscript
Also... what brought me here was that I wanted to run a multi line shell script using commands that are dynamically generated. I wanted all of my commands to run in the same shell, which won't happen using multiple calls to shell_exec(). The answer to that one is to do it like Jenkins - create your dynamically generated multi line of commands, put it in a variable, save it to a file in a temp folder, execute that file (using shell_exec in() php as Jenkins is Java), then do whatever you want with the output, and delete the temp file
... voila
If you are having a small script that you need to run (I simply needed to copy a file), I found it much easier to call the commands on the PHP script by calling
exec("sudo cp /tmp/testfile1 /var/www/html/testfile2");
and enabling such transaction by editing (or rather adding) a permitting line to the sudoers by first calling sudo visudo and adding the following line to the very end of it
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/testfile1 /var/www/html/testfile2
All I wanted to do was to copy a file and I have been having problems with doing so because of the root password problem, and as you mentioned I did NOT want to expose the system to have no password for all root transactions.