I am calling a bash script from PHP, but I have experienced a strange issue that only specific parameter value passed to bash can be successfully executed:
My PHP code is simple:
$result = shell_exec("/scripts/createUser.sh $uname");
Bash script code:
#!/bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
usrname=$1
echo -e "Username: $1"
deploy="/wordpress.tar.gz"
dest="/data/$usrname"
mkdir -p $dest
cd $dest
tar zxvf $deploy -C $dest >/dev/null 2>&1
ls $dest
However this script can only successfully mkdir, extract the wordpress.tar.gz and list the folder when $uname == 'test', otherwise nothing happen (even cannot mkdir).
I chown the script to www user and grant execution permission, no help. And already tried run these commands via console as root, they run fine:
/scripts/createUser.sh admin
php deploy.php // in this script $uname == 'admin'
How could this happen? Thanks for your idea!
I recently published a project that allows PHP to obtain and interact with a real Bash shell (as root if requested), it solves the limitations of exec() and shell_exec(). Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', false);
$return1 = $shell->exeCmd("/scripts/createUser.sh " . $uname);
//the return will be a string containing the return of the command
echo $return1;
But since you are simply triggering a bunch of bash commands, just issue them one by one using this project. That way you can also handle exceptions and see exactly which command returns something unexpected, i.e. permissions issues.
For commands that run for a long time you will have to change the timeout:
//is one hour enough?
$timeout = 3600000;
$return1 = $shell->exeCmd("/scripts/createUser.sh " . $uname, null, $timeout);
Related
I want to do some tasks on my server that require root shell access. I want to make a simple API that I can access from PHP.
The things I want to achieve is:
clone from one database to another. The databases are owned by different users:
mysqldump -h localhost -u SOURCE_USER -pSOURCEPASSWD SOURCE_DB | mysql -h localhost -u DEST_USER -pDEST_PASS DEST_DB
copy files from one user public_html to another:
cp -R SOURCE_DIR DEST_DIR
I have working bash-scripts for both those tasks.
I do not want to give PHP full root access to the server, since that would be crazy, but instead:
How can I make specified bash-scripts executable from a PHP-file in one linux-user's public_html directory?
Alternatively: How can I give root shell access (via shell_exec) to ONE specified PHP-file on a server.
You could use this project: Github. It allows PHP to obtain and interact with a real Bash shell even as root without running the web server as root.
After composer/downloading you would simply use the following code:
//read the documentation: here you get a root shell if you allowed sudo
$shellObj = \MTS\Factories::getDevices()->getLocalHost()->getShell("bash", true);
//OR if you did not want to give the webserver sudo access, then you can use this syntax:
$shellObj = \MTS\Factories::getDevices()->getLocalHost()->getShell("bash", false);
\MTS\Factories::getActions()->getRemoteUsers()->changeUser($shellObj, 'root', 'rootPassword');
//In both cases you now have a shell as root. This really is a bash shell, its not just wrapping the PHP shell functions.
//All you have left is to issue commands just like you would on a bash prompt
$strCmd = "mysqldump -h localhost -u SOURCE_USER -pSOURCEPASSWD SOURCE_DB | mysql -h localhost -u DEST_USER -pDEST_PASS DEST_DB";
//for the vast majority of commands that finish within 10 sec you need only issue the command
$return = $shellObj->exeCmd($strCmd);
echo $return;// return from your command
//However if your command runs for more than 10 sec, you must set a timeout. e.g.
//timeout in miliseconds
$timeout = 20000;
$return = $shellObj->exeCmd($strCmd, null, $timeout);
echo $return;// return from your command
Feel free to issue more commands on the $shellObj, its a bash shell ready to take orders and as i said ready the documentation.
After an useful comment from arkascha I researched sudo and found Ezequiel Hdez's answer in sudo in php exec() to be useful in finding the answer to my question:
Allow myuser to sudo my shell script by adding in sudoers file (access it by typing visudo):
myuser ALL = NOPASSWD: /path/to/myscript.sh
Make script executable:
chown u+x /path/to/myscript.sh
Then in PHP (from "myuser")
exec("sudo /path/to/myscript.sh argument1 argument2");
Now I was able to do whatever I want from PHP, but ONLY via /path/to/myscript.sh
I have a bash script that takes a parameter is called in PHP by shell_exec(script.sh parameter). Basically, my goal is to call a script that is owned by another user that is not apache.
The script.sh script is a file that contains the following (right now there are some error handling commands):
#/bin/bash
whoami>>whoami
echo $1 >> parameter
while read f; do
env>>envoutput
sudo -i -u archivescriptowner /path/to/archivescript.sh -command archive >> output
done < $1
In my /etc/sudoers file , I have the following:
apache ALL=(archivescriptowner) NOPASSWD: /bin/bash -c /path/to/archivescript.sh *
When I run this script as by running su -s /bin/bash apache and pass a parameter, it works.
When I run it via my button in php, archivescript.sh does not execute
The whoami file has apache written to it
The parameter file has the right file written to it
env shows the following
Term=xterm
LD_LIBRARY_PATH=/path/to/library
PATH=/sbin/:usr/sbin:/bin:/usr/bin
PWD=/var/www/html
LANG=C
SHLVL=4
=/bin/env
PWD is outputting right, that is where my script is right now, it will be moved in the future.
The output file when it is ran by the button click is blank.
I am at a loss as to why this is not working. Any insight would be helpful. Please let me know if I need to give any additional information.
I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('/path/to/archivescript.sh');
echo $return1; //return from your script
i want to execute a bash shell script in php. The shell script used to create make a directory. But it is not creating while i am running the .php file in server.
The php code for above i have used-------
<html>
<?php
echo exec('./home/biswajit/lh.sh')
?>
thanx
</html>
And the code for corresponding lh.sh file is------
#!/bin/bash
cat <<EOF | /home/biswajit/matlab -nodesktop -nosplash -nodisplay /> /home/biswajit/matlab_result.out
mkdir('/home/biswajit/Done');
disp('directory created');
exit
EOF
Check with which user's permissions it's run. You could echo the output of "whoami" (bash) command to know with wich user is used to run the script.
If it's executed, for example, with the "www-data" user (ubuntu's [and maybe others] default httpd user), then it may not have the rights to create a directory in your user's home folder.
I recently published a project that allows PHP to obtain and interact with a real Bash shell (as root if requested), it solves the limitations of exec() and shell_exec(). Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('cat <<EOF | /home/biswajit/matlab -nodesktop -nosplash -nodisplay /> /home/biswajit/matlab_result.out');
$return2 = $shell->exeCmd('mkdir -p \'/home/biswajit/Done\'');
//the return will be a string containing the return of the command
echo $return1;
echo $return2;
I am trying to Execute a multiple commands in php using exec() and shell_exec but i am getting a null value back which i shouldn't and nothing is happening (if i copy and paste the strings below in the command line it will work fine and accomplish the job needed) this is the commands i am using:
$command = "cd /../Desktop/FolderName;";
$command .= 'export PATH=$PATH:`pwd`;';
$command .= 'Here i execute a compiler;';
and then i use the escapeshellcmd()
$escaped_command = escapeshellcmd($command);
then
shell_exec($escaped_command);
any ideas what i am doing wrong and i also tried escapeshellarg() instead of escapeshellcmd()?
Solution: the Problem was the permission of the execution compiler for other owners is non and this was the problem.
because when you are using exec() function in php the owner of the file will be www-data so you need to give permission for the www-data either from the ACL of ubuntu or whatever linux based operating system(you can know the owner by doing this exec('whoami')), or by the files you need to execute.
(Sorry my bad English)
On Linux you can add your Commands in a Shell Script.
You can put this in any file:
#!/bin/bash
cd /../Desktop/FolderName
export PATH=$PATH:`pwd`
EXECUTE COMPILER
And save this as fille.sh
Then, add execution permissions:
chmod +x path/to/file.sh
From PHP, you can call this Script executing:
shell_exec('sh path/to/file.sh');
Hope this helps!
I have a PHP script that runs a .bat file on my windows machine using
$result = system("cmd /C nameOfBatchFile.bat");
This sets some environmental variables and is used to call Amazon EC2 API from the command line.
How do I do the same from a Linux server? I have renamed my .bat file to a shell (.sh) and changed the script to use 'export' when setting env vars. I have tested by running the code from a putty terminal and it does what it should. So I know the commands in the script are good. How do I run this from PHP? I have tried running the same command as above with the new filename and I don't get any errors, or file not found etc but it doesn't appear to work.
Where do I start trying to solve this?
---------------------------------- UPDATE -------------------------------
Here is the PHP script that calls the shell file -
function startAmazonInstance() {
$IPaddress = "1.2.3.4"
$resultBatTemp = system("/cmd /C ec2/ec2_commands.sh");
$resultBat = (string)$resultBatTemp;
$instanceId = substr($resultBat, 9, 10);
$thefile = "ec2/allocate_address_template.txt";
// Open the text file with the text to make the new shell file file
$openedfileTemp = fopen($thefile, "r");
contents = fread($openedfileTemp, filesize($thefile));
$towrite = $contents . "ec2-associate-address -i " . $instanceId . " " . $IPaddress;
$thefileSave = "ec2/allocate_address.sh";
$openedfile = fopen($thefileSave, "w");
fwrite($openedfile, $towrite);
fclose($openedfile);
fclose($openedfileTemp);
system("cmd /C ec2/mediaplug_allocate_address_bytemark.sh");
}
And here is the .sh file - ec2_commands.sh
#!/bin/bash
export EC2_PRIVATE_KEY=$HOME/.ec2/privateKey.pem
export EC2_CERT=$HOME/.ec2/Certificate.pem
export EC2_HOME=$HOME/.ec2/ec2-api-tools-1.3-51254
export PATH=$PATH:$EC2_HOME/bin
export JAVA_HOME=$HOME/libs/java/jre1.6.0_20
ec2-run-instances -K $HOME/.ec2/privateKey.pem -C $HOME/.ec2/Certificate.pem ami-###### -f $HOME/.ec2/aws.properties
I have been able to run this file from the command line so I know that the commands work ok. When I had this working on windows there would be a delay as the instance started up and I could echo the results to the screen. Now there is no delay as if nothing is happening.
Put a hash-bang on the first line of your shell script.
#!/bin/bash
Then give it the executable flag.
$ chmod a+x yourshellscript
You can then call it from PHP with system.
$result = system("yourshellscript");
$result = system("/bin/sh /path/to/shellfile.sh");
Is script executable? If not, make it so:
$ chmod a+x script.sh # shell
system ("/path/to/script.sh"); // PHP
or launch it via interpreter:
system("sh /path/to/script.sh"); // PHP
Is interpreter specified in shell script (ie. #!/bin/sh line)?
have you tried shell_exec() ?