I have this php code:
echo shell_exec('sh /backups/turnon.sh');
The /backups/turnon.sh code is:
screen -X 'cd /ftb; java -Xms2048m -Xmx2048m -jar mcpc.jar'
However, that outputs to the website:
No screen session found.
However if I open PuTTY and I do screen -x I can load the screen with no issue. What am I doing wrong.
Not sure why one would do this, but as a sample of one way to do it.
www-data
One way to solve this case would be to attach to correct user session. For Apache that is normally www-data which is a user with stripped down privileges. Use ps on apache or,
in PHP you can run this to show you which user PHP (Apache) run as:
<?php echo exec('whoami'); ?>
Output:
www-data
Note that if you run the script using PHP from command-line you will get current user, which you do not want.
Initiate screen session for www-data
www-data is normally not set up with password, as such we cannot log in with that user. To run a screen session for www-data one can do the following:
$ sudo su - www-data
$ script /dev/null
$ screen
Or as a one-liner:
sudo su - www-data -c 'script -c screen /dev/null'
This will start a new shell in www-data's home directory, typically /var/www/. The script command is one way to prevent access error to terminal when running screen due to the use of sudo su.
Execute script from PHP
Now that we have a screen session for www-data we can continue with the Bash script.
/usr/bin/screen -X stuff '/usr/bin/java -cp /some/path/ Test
'
and execute it from PHP.
Capturing output
If you want the buffer from screen in PHP there is various ways:
First create a log-file for www-data's screen session.
touch /tmp/www-data-scr.log
chown www-data:www-data /tmp/www-data-scr.log
Use logfile option in .screenrc and run screen with -L.
Run script -f /tmp/www-data-scr.log inside screen.
Start www-data script screen session with log-file, -f to flush.
sudo su - www-data -c 'script -fc screen /tmp/www-data-scr.log'
Copy buffer to file to get a snapshot.
/usr/bin/screen -X hardcopy /tmp/www-data-scr.log
etc.
You would typically add a
sleep N
in your bash script after issuing the command producing some output and before reading the log file.
To sum up
As privileged user:
touch /tmp/screen.log
sudo chown www-data:www-data /tmp/screen.log
sudo su - www-data -c 'script -c screen /dev/null'
Bash script:
#!/bin/bash
/usr/bin/screen -X stuff 'java -cp /some/class/path/ Test
'
sleep 1
/usr/bin/screen -X hardcopy /tmp/screen.log
sed '/^$/d' /tmp/screen.log
PHP:
<pre>
<?php
echo "-----------------------------------------------------------\n";
echo htmlentities(shell_exec('sh /path/to/script'));
echo "-----------------------------------------------------------\n";
?>
</pre>
The man page for screen specifically states:
-x Attach to a not detached screen session. (Multi display mode).
-X Send the specified command to a running screen session.
The error message you're getting says that there's no existing screen process running to attach to. Something is different between your PuTTY login environment and the environment in which the script is trying to run, possibly that you have a screen session running as your PuTTY login user but none running as the user running the script.
Related
On a local linux server (Rapsberry Pi debian stretch with desktop), I am working on sending "audtool" commands to a running Audacious media player using php, exec and bash scripts. Audacious is autostarted when the server starts up with user "pi". I have apache2 and php set up and working on the server, and I can ssh to the server and run all the commands from the cli. I believe I have resolved the issues with running audtool (dbus and setting the right environment variables) and running the php on the command line works successfully. However when running the php on a webpage I get back a long string of information about apache2
I have spent several hours (getting on for a whole day) researching this on the web in order to get to this stage, so close I can almost touch it, but stuck on this last element. The example is to display the current song from a running instance of Audacious. Audtool requires a running dbus (looks for a display). Using exec or shell_exec I have no problems running bash commands such as whoami or ls.
The php page (cursong.php):
<?php
echo exec('/var/www/html/cursong.sh');
?>
The bash script (cursong.sh):
#!/bin/bash
##call current song
pid=`pidof audacious`
user=`ps -p $pid -o user=`
export `strings /proc/$pid/environ | grep DBUS_SESSION_BUS_ADDRESS`
sudo -E -su $user /usr/bin/audtool --current-song
(from here: https://redmine.audacious-media-player.org/boards/1/topics/1058?r=1059)
Output from command line:
php -f cursong.php
Artist - Song Title (for example - so this works)
Output on webpage:
declare -x APACHE_LOCK_DIR="/var/lock/apache2" declare -x
APACHE_LOG_DIR="/var/log/apache2" declare -x
APACHE_PID_FILE="/var/run/apache2/apache2.pid" declare -x
APACHE_RUN_DIR="/var/run/apache2" declare -x APACHE_RUN_GROUP="www-
data" declare -x APACHE_RUN_USER="www-data" declare -x
INVOCATION_ID="4ce76136ca8842bd9108d6b1b9a5b9ed" declare -x
JOURNAL_STREAM="8:23896" declare -x LANG="C" declare -x OLDPWD
declare -x
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
declare -x PWD="/var/www/html" declare -x SHLVL="1"
I have set www-data, the apache2 user with the following in
/etc/sudoers:
www-data ALL=NOPASSWD: ALL
and /var/www/html is rwx for anyone
Obviously, I am expecting to see "Artist - Song Title" on the webpage, but instead I get back all the apache2 info. What am i missing, or where have I gone wrong?
I hate answering my own question, makes it look like I wasn't trying hard enough! After a further five hours or so of searching around and attempting fixes, I happened upon this post on SO:
Running command-line application from PHP as specific user
which suggested putting a "sudo -u user" in the exec of the php file. I tried this with the "pi" user and it still didn't work, then I simply tried it with "sudo" and hey presto!!
The php file now looks like this:
<?php
echo shell_exec('sudo /var/www/html/cursong.sh 2>&1');
?>
Now to do some testing on how it works with the other audtool commands that don't ask for a response but require action from audacious, and to see how I can reduce scripting php files by passing a parameter to the bash script!
Just for completeness, the php and bash scripts for both a request and an action, using a parameter fed to the php url and then on to the bash script:
PHP File with Parameter
<?php
$request = $_GET["request"];
echo shell_exec("sudo /var/www/html/cursong.sh \"${request}\" 2>&1");
?>
url example:
http://192.168.1.92/cursong.php?request="--playlist-shuffle-status"
Bash Script with parameter
#!/bin/bash
##call request
pid=`pidof audacious`
user=`ps -p $pid -o user=`
export `strings /proc/$pid/environ | grep DBUS_SESSION_BUS_ADDRESS`
sudo -E -su $user /usr/bin/audtool $1
PHP file for an action
<?php
$action = $_GET["action"];
shell_exec('sudo /var/www/html/playsong.sh \"${request}\" ');
?>
url example:
http://192.168.1.92/cursong.php?action="--playback-play"
Bash script for an action
#!/bin/bash
##call action
pid=`pidof audacious`
user=`ps -p $pid -o user=`
export `strings /proc/$pid/environ | grep DBUS_SESSION_BUS_ADDRESS`
sudo -E -su $user /usr/bin/audtool $1
I an Ubuntu 16.04 machine running NGINX and PHP. I would like to enable the www-data user (via web browser) to be able to access a PHP page (php-test.php) that will execute either a bash script (script_test.sh) or execute Linux CLI commands using shell_exec or exec.
I have done the following.
Created my bash script file script_test.sh
#!/bin/bash
whoami
echo $USER
echo 'test'
exit
when I run this from CLI, using
./ script_test.sh
It does indeed work and I can see the info echoed out in the CLI.
I then pursued the goal of being able to allow the www-data user run this bash script through a PHP page running on this same machine from NGINX.
I created my php page (php_test.php) and it contains the following
<?php
chdir('/path/to/my/files/');
shell_exec('./script_test.sh'); // ATTEMPT RUN SCRIPT
shell_exec('/path/to/my/files/script_test.sh'); // ATTEMPT RUN SCRIPT
echo 'test 123'; // SIMPLE ECHO IN THE PHP PAGE
?>
I then ran the following to modify the sudoers file, giving www-data access to the bash script
sudo nano /etc/sudoers
to which I added the following line
www-data ALL=NOPASSWD: /path/to/my/files/script_test.sh
I then made sure the script was executable, for the sake of my testing, not worrying about security, I just set it to 777 with the following command
sudo chmod 777 script_test.sh
From there I opened a web browser and browsed to the localhost (NGINX) web server (php_test.php) and the only thing I see on the page is the 'test 123' that I echo from PHP... none of the bash script appears to have run at all. I tailed the NGINX error log and don't see any error at all.
Is there another log that could contain clues on this?
What else should I check here?
The result of shell_exec() is returned as string. To display it in your browser, simply add echo.
<?php
chdir('/path/to/my/files/');
echo shell_exec('./script_test.sh'); // ATTEMPT RUN SCRIPT
echo shell_exec('/path/to/my/files/script_test.sh'); // ATTEMPT RUN SCRIPT
echo 'test 123'; // SIMPLE ECHO IN THE PHP PAGE
?>
See the Return Values in the manual:
The output from the executed command or NULL if an error occurred or
the command produces no output.
Can you try to use passthru instead of shell_exec, and see the output anything?
Also try this, and see if it shows on the log file:
if(file_exists('/path/to/my/files/script_test.sh')) { die('File not found!'); }
shell_exec("nohup /path/to/my/files/script_test.sh > /path/to/my/files/output.log &");
Also, are you running PHP with the www-data user (check your fpm pool)?
Do you have any error on /var/log/syslog or /var/log/auth.log ?
Have you restarted the server after changing the sudo permissions?
What does su - www-data -c "whoami" and su - www-data -s /bin/bash -c "whoami" outputs?
Does su - www-data -s /bin/bash -c "/path/to/my/files/script_test.sh" output something?
I have an sh file with file-removing commands.
I run it from php like this:
shell_exec("sudo -n ./truncatefiles.sh 2>&1");
Thats works fine if I open the PHP file from browser, but doesnt work from scheduled cron tab.
PHP user: www-data
If i run whoiami from cron, returns same: www-data
I added this to my visudo:
www-data ALL=(ALL) NOPASSWD: /www/sites/..../importscript/truncatefiles.sh
Shell exec for this sh file returns (from cron):
sudo: sorry, a password is required to run sudo
Why works it dirrefent way in cron?
What should I do for get it work?
PLease try to do the following,
Try to log your output from crotab to a file,
* * myscript.php >> /var/log/myjob.log 2>&1
This way you can debug your script.
1. Also the check the user and permissions for your shell script, php file.
2. try with sudo crotab -e
I want to start program when I enter my webpage, and problem is in permissions(??) because when I try
echo exec('whoami');
I've got valid response (www-data) but when i try code like it:
echo exec('/var/www/./sitesend');
and
echo passthru(/var/www/./sitesend');
I got no response. I tried to
chown www-data /var/www/sitesend
chmod 755 /var/www/sitesend
My C++ app runs correctly, and its sending by NRF infromations to turn lights.
But not work, when enter page app won't run and I don't get any reps in echo.
I don't have a conclusive answer, but you can try a number of things:
Try the follow command to see if www-data may run the command.
sudo -u www-data /var/www/sitesend
Try running a PHP script with the passthru command from the commandline.
See if you're running AppArmor for the Apache process. AppArmor will block execution for files not white listed.
ls /etc/apparmor.d
I have a PHP script that starts a detached screen through SSH:
$ssh->exec("screen -m -d -S ".$user);
I now need to execute a command in that screen without being in that screen. I have the code that does that, which I have tested through a SSH client, but when I try to use it with the phpseclib exec command, it does not work. This is the code that works:
screen -S ".$user." -X stuff "cd minecraft/servers/".$user."/;sh start.sh $(printf '\r')"
And this is it in the PHP script:
$ssh->exec("screen -S ".$user." -X stuff \"cd minecraft/servers/".$user."/;sh start.sh $(printf '\r')\"");
I attempted to escape the extra double quotes in the code.
Is there anything I can do to make this work through PHP? Thanks
Hmmm...
create please two bash script, first: create screen with user parameter with name f.e. run_screen, second: tester for SSH client with user parameter with name f.e. run_test.
Run first script:
$ssh->exec('[full_path]/run_screen ' . $user);
and second:
$ssh->exec('[full_path]/run_test ' . $user);
bash syntax is here bash syntax
Sure that the user of server (f.e. Apache) has permissions to run scripts.