PHP script can't run bash script. sh: Permission denied
Solution 1
Try the following suggestions:
- Try to run below test command, and check whether it worked:
php -r "echo exec('whoami');"
- Make sure that all parent directories and the files have at least
r-x
flag permissions:chmod 755 dir; chmod 755 file
- Make sure that the owner of the file is your Apache user.
- Try also to add a
+s
flag (sudo) to the file (not recommended):-
chmod u+s file
,
-
- Try also to add a
- Make sure that your PHP is not running in a
safe_mode
. - Make sure that the script is inside your Apache root:
- Otherwise, move the script inside it,
- or add that directory to your Apache configuration,
- or add this directory to your
include_path
, e.g.:-
php.ini
file:include_path ".:/usr/local/lib/php:/your/dir"
- or
.htaccess
file:php_value include_path ".:/usr/local/lib/php:/your/dir"
-
- Check whether your shell is set to valid (e.g.
/bin/sh
) to your Apache user (e.g. check with:finger
). - Make sure that your
php.ini
doesn't use:disable_functions
forexec
function - If using SELinux or having
selinux-utils
installed (a Security-enhanced Linux system), checkgetenforce
/setenforce
configuration as described in @Tonin answer.
Troubleshooting:
- If you changed your
php.ini
orhttpd.conf
file, don't forget to restart the web server, - Check your Apache error log for additional details.
- Enable in your
php.ini
all kind of errors (display_error
,error_reporting
, etc.).
Solution 2
Such an issue might depend on the OS you use and how it is configured. Some linux distros (mainly those based on RHEL like CentOS or Fedora) come with SELinux activated by default. This can be checked, and temporarily changed, with the following commands:
root@ls:~# /usr/sbin/getenforce
Enforcing
root@ls:~# /usr/sbin/setenforce Permissive
root@ls:~# /usr/sbin/getenforce
Permissive
You can also have a more complete view on the current configuration with:
root@ls:~# /usr/sbin/sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: permissive
Mode from config file: enforcing
Policy version: 21
Policy from config file: targeted
This change can be made permanent by editing the /etc/selinux/config
file and set the SELINUX
variable to permissive
or disabled
.
But, the correct way to solve this kind of issue, if you are indeed in this situation, is to check the /var/log/audit/audit.log
log file. It will contain all the events related to SELinux rules. You'll then probably should give your script the correct context, i.e. being authorized to be run by the apache/php user. Checking SELinux security context is done with ls -Z
:
root@ls:~# ls -alZ /var/www/cgi-bin/
drwxr-xr-x root root system_u:object_r:httpd_sys_script_exec_t .
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t ..
This list the User, the Role and the Type of each file/directory. Here the httpd_sys_script_exec_t
type gives the files in the cgi directory the permission to be executed by httpd. Your shell script should probably have the same type.
You can also feed the audit.log
lines to the audit2allow
command. It will output you the changes needed to make SELinux happy. But usually the changes suggested need to be done on the SELinux policy itself which is not what you should do in your case (still, this output can give some clue at what is going on).
The following page describe a similar issue and different ways to solve it: http://sheltren.com/stop-disabling-selinux
Solution 3
So I got here after searching for a similar issue on Google. I thought to drop that the comment about SELinux pointed me in the right direction.
In my own case, I was using a custom Git deploy script that uses a shell command. The command works fine on BASH but then has "permission denied" and "not a repository" on Git. This was really strange and I went through multiple fixes until I stumbled on this answer.
root@ls:~# /usr/sbin/setenforce Permissive
solved the problem for me.
Related videos on Youtube
Kunegundek
Updated on September 18, 2022Comments
-
Kunegundek over 1 year
I'm trying to exec a .sh script from PHP, however it is not executing.
I checked the error logs, and I'm getting the 'sh: Permission denied' error. I checked under which user php is being run, and it's done under the apache user.
I tried changing the .sh's ownership to the apache user, but there is no result.
I thought at first this was because the script was outside the www/ dir, however even when I put the script in the same directory, the error is still being given.
Are there any solutions to this other than adding the apache user to the SUDOers list?
The sh script runs fine if I launch it from putty using the 'php filename.php' command.
-
Kunegundek almost 12 yearsIt's a bash script to be ran from PHP. Yes I did make it an executable and I did specify the script interpreter. It works correctly when I execute the PHP script from putty and the bash script gets called and runs correctly. But if I run the php script from the webbrowser instead it fails to run the bash script and it will do this error since it's running as the apache user and not the user I use in putty.
-
Rossco Stringer almost 12 yearsTry
chmod 775 yourscript.sh
. That will giver-x
(read and execute) permissions to "Other" users on that file. -
Kunegundek almost 12 yearsI tried it. No luck.. I can't know the exact reason until tomorrow though. I don't have access to the logs from my location. I will get back to you guys. Thank you for your help. :)
-
-
Kunegundek almost 12 yearsThank you for the detailed reply! Alas, like I mentioned I can't have root access until tomorrow. So I will get back to you too! :) And yes, I am using CentOS.
-
Kunegundek almost 12 yearsThat was my problem.. the parent directory didn't have execution rights... it works now! Thank you! :)
-
Kunegundek almost 12 yearsI loved your answer, very informative! Unfortunately I didn't pick yours because the enforce was disabled and wasn't the problem. Though I did learn a lot from your answer, so thank you. I will vote you up when I get enough reputation :)
-
Læti almost 12 yearsNo worries, glad to know you learned from my post!
-
pihentagy over 8 yearsStill no luck for me :( Any suggestions?``` [root@kiwi tmp]# ls -ld /;ls -ld /tmp;ls -ld /tmp/sleep;grep '^include_path =\|^safe_mode =' /etc/php.ini dr-xr-xr-x. 27 root root 4096 Sep 3 12:31 / drwxrwxrwt. 4 root root 4096 Sep 3 15:45 /tmp -rwxr-xr-x. 1 root root 24 Sep 3 15:39 /tmp/sleep safe_mode = Off include_path = "/tmp:/home/kiwi_build"```
-
pihentagy over 8 yearsArgh, setenforce solved it. OMG
-
pihentagy over 8 yearsIf getenforced is the problem, then it is really not obvious what the heck is going on. It saved my day!
-
Thalys over 7 yearsThis is a terrible idea. If your apache install gets compromised or the application you're running does... your hacker gets full access to the system much too easily. The right thing is to change permissions on the script, not leave things wide open
-
Ramhound over 7 yearsI feel obligated to issue a downvote on this answer due to the obvious security concerns with give apache user/role all permissions.
-
Michael Hampton about 7 years@JourneymanGeek It's not "if", it's when the install gets compromised.