1

I am new to linux and the script below is just an example of my issue:

I have a script which works as expected when I execute it however when I set it to run via crontab it doesn't work as expected because it doesn't read the file content into the variable.

I have a file 'test.txt' which has 'abc' in it. My script puts the text into a variable 'var' and then I echo it out to a log file:

var=$(</home/pi/MyScripts/test.txt)
echo "$var" >/home/pi/MyScripts/log.log

This works perfectly fine when I execute it and it echo's into the log file but not when I set it via crontab:

* * * * * /home/pi/MyScripts/test.sh

The cron job runs, and it sent me the following error message:

/bin/sh: 1: /home/pi/MyScripts/test.sh: Permission denied.

But I have given it 777 permissions:

-rwxrwxrwx 1 pi pi   25 Jun 10 15:31 test.txt
-rwxrwxrwx 1 pi pi   77 Jun 10 15:34 test.sh

Any ideas?

timrau
  • 22,578
  • 4
  • 51
  • 64
  • 5
    Make sure to put the shebang on top. Like `#!/bin/bash`. – Tripp Kinetics Jun 10 '14 at 16:43
  • How often do you want it to execute? Every minute? – Jonathan Wheeler Jun 10 '14 at 16:43
  • If it couldn't open the file you would get an error message emailed to you. – Barmar Jun 10 '14 at 16:44
  • /bin/sh: 1: /home/pi/MyScripts/test.sh: Permission denied. But I have given this file 777 permissions. – user3726871 Jun 10 '14 at 16:46
  • @user3726871 Edit it into your question. – timrau Jun 10 '14 at 16:46
  • Do you have +x on all the directories leading up to the script? – that other guy Jun 10 '14 at 16:52
  • @thatotherguy This is irrelevant if the script can run well outside of a cron job, “Do you have +x on all the directories leading up to the script?” The big clue is the error shows `/bin/sh` but the user created a `bash` script. See my answer for details. – Giacomo1968 Jun 10 '14 at 16:55
  • @JakeGould You're assuming the cron job runs as `pi`. Why would no shebang give a "Permission denied" error executing the script? – that other guy Jun 10 '14 at 17:04
  • 2
    Whatever other problems you may have, 0777 is always wrong, and a security risk. Sane permissions for this would be e.g 0755. – tripleee Jun 10 '14 at 17:04
  • @tripleee Exactly. I posted about the `777` issues my answer. – Giacomo1968 Jun 10 '14 at 17:06
  • @thatotherguy If the file itself has execute permissions & you have the full path of the file, the parent directory permissions are meaningless. Also, “Why would no shebang give a "Permission denied" error executing the script?” perhaps because the whole syntax is incorrect for `sh` so I assume it attempted to do something with the `$()` that it believed was file system based? – Giacomo1968 Jun 10 '14 at 17:09
  • 1
    @JakeGould You need +x on all directories leading up to execute a script, even if the script itself is 777 and you use absolute path. Also, the error is in executing `/home/pi/MyScripts/test.sh`. Not executing line 1 of this file. – that other guy Jun 10 '14 at 17:14
  • @thatotherguy Okay, fair enough. Rough day & mixed concepts up. Cheers! – Giacomo1968 Jun 10 '14 at 17:22

3 Answers3

2

This happens when you run the script with a different shell. It's especially relevant for systems where /bin/sh is dash:

$ cat myscript 
echo "$(< file)"

$ bash myscript
hello world

$ sh myscript

$ 

To fix it, add #!/bin/bash as the first line in your script.

that other guy
  • 116,971
  • 11
  • 170
  • 194
1

Others have provided answers, but I will give you a big clue from your error message; emphasis mine:

/bin/sh: 1: /home/pi/MyScripts/test.sh: Permission denied.

Note how the cron job was trying to use /bin/sh to run the script. That’s solved by always indicating which shell you want to use at the top of your script like this.

#!/bin/bash
var=$(</home/pi/MyScripts/test.txt)
echo "$var" >/home/pi/MyScripts/log.log

If your script is using bash, then you must explicitly set /bin/bash in some way.

Also, regarding permissions you say this:

But I have given it 777 permissions:

First, 777 permissions is a massive security risk. If you do that it means that anyone or anything on the system can read, write & execute the file. Don’t do that. In the case of a cron job the only entity that needs 7 permissions on a file is the owner of the crontab running that file.

Meaning if this is your crontab, just change the permissions to 755 which allows others to read & execute but not write. Or maybe better yet change it to 700 so only you—as the owner of the file—can do anything to the file. But avoid 777 permissions if you want to keep your system safe, stable & sane.

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
  • 1
    0755 is read and execute for group and other, not read and write (it's writes you want to block anyway). – tripleee Jun 10 '14 at 17:09
  • @tripleee You are correct. Mixed up a bit today. `755` is good because it allows group members & others to execute as well as read the file. But they cannot write. Which is a useful way to allow access but not risk accidental over writing of content in an executable. – Giacomo1968 Jun 10 '14 at 17:12
0

You have two options. In the first line of your file, tell what program you want to interpret the script

#!/bin/bash
...more code...

Or in your crontab, tell what program you want to interpret the script

* * * * * bash /home/pi/MyScripts/test.sh

In this option, you do not need to make the script executable

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
Jonathan Wheeler
  • 2,539
  • 1
  • 19
  • 29