Permission denied with bash.sh to run cron - php

How to run a cron with bash script here.What i did as follows and here with errors.I want to know how to do that in ubuntu.I was struck with it now
bash.sh file
#!/bin/bash
cd /var/www/Controller
/usr/bin/php post.php
In crontab -e
* * * * * /home/samitha/bash.sh >> /home/samitha/log/cron.log 2>&1
But now i getting following error
/bin/sh: 1: /home/samitha/bash.sh: Permission denied
How will i fix it ? what i did wrong ?

you can try the following solution as well:
chmod +x post.php
chmod +x bash.sh
echo "* * * * * /home/samitha/bash.sh >> /home/samitha/log/cron.log 2>&1" >> cronjob
chmod +x cronjob
/etc/init.d/crond start #redhat based servers like centos
/etc/init.d/cron start #debian based servers like ubuntu
crontab cronjob

The problem could be that your user does not have the rights to execute the file.
First you set the execution flag for your script
chmod +x /home/samitha/bash.sh
Then you should check the permissions for the php file with
ls -lah /var/www/Controller
If neither your usergroup nor your username shows up, you have to run the script with superuser rights or change its permissions.
First way would be put your entry in
sudo crontab -e
or the second one would be (which I would not recommend, as everyone would be allowed to execute the script by calling your site)
chmod a+x /var/www/Controller/post.php

The user executing that cron (the one who executes cron -e) doesn't have proper rights for executing that script. That is: either the script lacks the execution flag, or it's not possible to reach it because some of its ancestor directories lack the execution flag.

TL;DR: Insert "bash" before the script in crontab and in any scripts called by the script.
I have a fix for this. None of the previous answers worked for me. I have two Asus laptops running Kubuntu (updated to kernel v5.8) with virtually identical configurations. I don't know why one has the problem and the other doesn't. However, after 2 days of experimentation I found a fix. Hopefully, someone more knowledgeable than I can find the cause.
Cron is using sh instead of bash. I tried adding SHELL=/bin/bash and defining PATH above the commands in crontab and it had no effect. All of my scripts have the #!/bin/bash shebang at the beginning, also with no effect. My scripts' (and their directories') permissions are 777. The scripts don't run for cron or users, no matter what combination of user:group I tried on the files. Using full pathnames is cron and inside the scripts had no effect that was different from using environment variables.
My fix was to insert "bash" before the script filename in crontab. E.g.:
00 01 * * * bash $BASH_SCRIPTS/backup_os.sh
(Yes, cron has no problem with using my environment variables defined in /etc/environment.) Also, in cron, when a script runs another script, the second script will get "permission denied" unless that script is modified to have "bash" before the 2nd script's filename, or use "source" if that'll work with your script.

File must be executable (#see chmod)
All parent directories must have the execution flag (#see chmod)
If crontab is running by different user i.e. not owner, maybe this user don't have rights to execute. (#see chown)

I had exactly the same error as the OP, but on RHEL. Of course it was not a cron issue, but permissions. I should have checked this by trying to run the script manually, but I did not, because it worked well on other servers and file permissions were OK. Eventually, after a couple of hours scratching my head, I figured that the cause was that on this particular server the FS with home directory was mounted with noexec option (use for example mount | grep home to check mount options for /home). Another detail to keep in mind.
EDIT:
I read some more and it turns out that using noexec on the FS with home directories is now advisable for "security" reasons (although the point of doing this is debatable). I also realized that probably yendao42 had the same problem, because indeed adding bash in front of bash scripts is a very simple workaround for this exact issue.

Related

Running a PHP script that runs a Python script that runs a bash script, hangs on bash

I have a Python script which is encoding a video and then calling a shell script which uploads the new video to dropbox. It works fine from the command line but I needed to make it so others could execute it so I have a PHP script calling the python script.
I don't want the PHP script to run forever (it takes 15-30 mins for it to complete), I just want it to kick off the python script and be done. I figured out what I need to make that happen and like I said it works on the command line. But when it is called via PHP, the video encodes but the file never uploads. I can see the dropbox script was kicked off and is listed as a process using some percent of CPU, that percent never changes, it seems stuck/dead.
the command looks like this, being run using cmd()
script.py -options &>/logs/phptopython.log &
The shell script is kicked off using Popen
Any suggestions?
thanks
It sounds like this could be a permissions issue. Double check the permissions on the directory to which you are trying to upload the video. If you are on Linux you can modify the permissions on that directory like this:
chmod 755 /path/to/dir
This gives the file owner read, write and execute permissions (7). The group and other users get read and execute permissions (5).
Apache is likely running as a different user than when you run the command yourself in bash. A quick test to see if it's a permission issue would be to grant 777 on that directory. I wouldn't leave it that way though – it'd just be a way to quickly identify if permissions are the issue.
If the script works with 777 permissions, you could either change the owner of the directory to the user Apache runs as or add the Apache user to the directory's group and grant the group write permisssions.
Edit:
I just noticed you said you use cmd(), so I'm guessing you are on Windows. My comments might still be relevant but the chmod command won't work on Windows.

"exec('sh foo.sh')" in PHP not working

I've recently set up my Apache2 Server on my Linux machine. Now I've wanted to execute a PHP script (index.php), which runs a shell script (foo.sh), which creates a folder in my home directory, but the directory was not created.
These are the original two files:
foo.sh:
#!bin/bash
mkdir /home/lorenzo/testDir
index.php:
<?php
exec('sh test.sh');
?>
So, I thought maybe the problem occurs because of privileges or something, and indeed after I changed the files to that:
foo.sh:
#!bin/bash
echo "Hello world"
index.php:
<?php
$temp=exec('sh test.sh');
echo $temp;
?>
I saw the output Hello World on my website.
So the PHP script is executed and it runs the shell script. But why can't the shell script execute the mkdir command?
This indeed is most likely a permission issue.
You first have to figure out which user apache runs at. This is usually www-data (on Debian-ish Linuxes, such as Ubuntu) or apache (on RedHat-ish Linuxes) or something along the lines. A ps -eF | grep apache will reveal the user.
After you figured that out, make sure that the apache user has the appropriate rights in your home directory. You can either add it to your user group (using usermod -a -G ... and then chmod g+w ~) or allow writing for all users (chmod o+w ~).
But, both of this is a bad idea. Your php script (or anything else running as the apache user) can be broken into and cracked, leaving you home directory open for malicious attackers to modify and rm -rf.
In addition, if you’re running a RedHat-ish Linux, you will run into SELinux which by defaut prevents apache from accessing user directories at all. In that case, you also have to set setsebool -P httpd_enable_homedirs on.
Instead, I would recommend that you use a different directory and give your user full access to that. Something along the lines of /var/www/testDir with the apache as owner and group, and adding yourself to the apache user group is probably a sane idea.
It looks like a permission issue. Make sure that Apache has write permission to that directory
You may have permission issues on the server. Try to use chmod -R 775 <dirname>(or 777) in your ssh command line. You can do this in php code with chmod() too but I don't suggest you because it would run it everytime the php code runs and changing it more times is pointless. It can output to the screen but I bet the directory the script wants to make file has permission 755. Try to check it.

php script to execute python script to write some files

I have a php script that calls a python script which in turn is in charge of writing some files to disk.
If I execute the php script by entering its url in the web browser it can perform several filesystem related tasks:
it's able to create a dir
it's able to chmod the dir
but it's not able to execute the python script which would create and write other files.
The strange thing is that if I run the python script manually as www-data:
user#host $ sudo su www-data
passwd for sudo:
$ whoami
www-data
$ python my_script.py
It works like a charm.
I'm assuming the user when I run the script through the browser is www-data. So why is the result in the console any different?
SOLVED:
Python script starts off by importing some modules from my repository, which are appended to the path via .bashrc or .bash_profile on login consoles. These modules were not available from the browser to the user www-data. So adding this to the python script solved it:
import sys
sys.path.insert(0, 'path_to_my_modules')
solved it.
I apologize for the question. It didn't bring all the necessary information for users to lead to a solution. I guess the problem was so broad that it was difficult for me to start thinking of where its root was.
I lacked a good debugging technique to see what the error was. I commented out all the python script and begun with a simple print 'here'. Uncommenting lines one by one showed me the place where it just didn't print anything anymore (the error was obvious then).
First of all, don't assume that the user is www-data. You should get the output from whoami running from the PHP script to see if it is www-data. Also, you need to make sure your script has +x or execute permissions for the user.
You should read about execute permissions.
You need to use chown on your PHP script to change the ownership to the www-data user:
sudo chown www-data:www-data yourscript.php
Then you need to give the user execute permissions:
sudo chmod u+x yourscript.php

Kill a process from website

I have the code and everything which is:
pkill python
However I wanted to run it from a php script like this:
echo shell_exec("pkill python");
I get an output which says:
bash: pkill: (1503) - Operation not permitted
I know what the problem is, which is that pkill is su command. Anyway to change this so that the php script can run it?
The problem is, that the process you want to kill does not belong to the apache user (apache usually runs as www-data with group www-data). If you give apache more rights (say run it as user root), your PHP script would run with more rights and could do things like this. But this would be dangerous, because if there is a security flaw in apache or your php script, a malicious attacker could take over your system.
Instead I suggest using the setuid bit.
Create a file kill.sh with the content pkill python
Make it executable (chmod a+x kill.sh)
Make it belong to root (chown root:root kill.sh)
Make it setuid (chmod u+s kill.sh)
Invoke this script from your php script

How do I get a PHP file to automatically run itself?

I have a PHP file, x.php, that outputs b.xml every time it is run. The way I do this is by using crontab to run the x.php file. The problem is that due to the server's settings, the new file has permissions of 400. So I also have another crontab line to change file b.xml permissions to 777 so that x.php can run over it next time.
I feel like I am making this too complicated. Is there any way to make this a bit simpler?
Quick Answer
You'll need to chmod the file to be 777 in the x.php script.
After b.xml has been created, run this line:
chmod('path/b.xml', 0777);
Note you should always specify octals when using chmod.
A better way?
When you run a cron job, you should take special note of the user that is running the cronjob.
Generally on a shared server you will have your own login and thus the cron job runs as that user. My question to you - is that user the same as your web server? often php runs as "apache" and cron might be running as "tanner". In that case, setting b.xml to be owned by tanner, and having a permissions 400 means that only tanner can change the file.
To solve this, if you don't have access to umask, one way would be to change your cron job to run as the webserver:
su -c "php /home/jonathan/public_html/b.php" apache
This may or may not work depending if you are allowed to switch to apache as the user. do not forget to switch apache to the actual web servers username.
Now, if that doesn't work, then the alternative is to go for the 777 permissions. Keep in mind on a shared server this means anyone on that server could potentially get to that file if they knew the path.
Another way as suggested by OP:
0,10,20,30,40,50 * * * * /usr/bin/wget http://example.com/user/x.php
This way will always run as the apache (or whatever) user that apache runs as, ensuring the next time it is accessed, the file will be useable.
Ask the server admin to create a new user who owns the folder where the script writes the xml file.
Run your php script through your cron job as such user. If you run your script as the folder's owner you might change the permissions through your php script.
This should work:
// set permission
chmod('path/to/b.xml', 777);
// do other stuff
To solve this issue, I ended up just creating a cronjob such as this:
0,10,20,30,40,50 * * * * /usr/bin/wget http://example.com/user/x.php
This executed the file which created b.xml and since the user who executed the script was public, the permissions remained public as well.

Categories