I asked a similar question over here:(Upload clocking script), but then changed it and realized it's a different question now.
I want to make a script called uploadtimer.sh which uploads files to various hosts and then notes the time the upload takes in a log file. Thanks to those who have helped me, I have a partial solution but I'm stuck:
I used this as a crontab (testing it for the first ten minutes after 11 am)
1,2,3,4,5,6,7,8,9,10 11 * * * /usr/bin/time -a /usr/local/apache/sites/$MYEMPLOYER/upload_test/output.log /usr/local/apache/sites/$MYEMPLOYER/upload_test/uploadtimer.sh
upload_test/ has these files in it:
upload_test/output.log
upload_test/uploadtest.gif
upload_test/uploadtimer.sh
output.log is a text file that I renamed as a .log file. It's blank. Before I put it there, I was getting messages that said "this file doesn't exist". I thought it'd create one for me but I guess not. After I created it, it kept saying in the crontab mails that I couldn't write to it until I changed its permissions, so I did.
uploadtest.gif is a gif
uploadtimer.sh is this:
#!/bin/sh
HOST='--myhost--'
USER='--login--'
PASSWD='--password--'
FILE='uploadtest.gif'
ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
put $FILE
quit
END_SCRIPT
exit 0
The message that cron sends to me is:
0.00user 0.00system 0:00.02elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+253minor)pagefaults 0swaps
But no ftp has taken place and nothing it written in output.log.
Create another script that runs the second command. Call the second script from cron.
You will need to make sure you are using absolute paths for everthing because cron starts in a different directory than the script.
Your questions:
Where do I put this part, which tells it to save the data to a log?
You edit your crontab file to add a cron entry. The cron entry contains information regarding what command to run and when to run it. For example, here is a cron entry that you might use:
0 2 * * * /usr/bin/time -a ~/output.log ~/uploadtimer.sh
This entry says to run the command at 2AM every day (minute 0, hour 2, every day of the month, every month, every day of the week). For more info on the crontab syntax, you can check out http://www.adminschoice.com/docs/crontab.htm .
To make a cron entry, use the command crontab -e which will load up a vi text editor. Enter the line above and then save it. This creates the cron job. If you don't know vi, just follow this:
from the shell, enter crontab -e to start editing
press i to enter Insert mode
enter the line as above
press ESC to exit Insert mode
press : to switch to Command mode - you will see the cursor at the bottom of the screen
enter wq and hit Enter - this Writes and Quits the file. You should see a message like crontab: installing new crontab.
If you run into any problems using vi, use ESC a few times to exit whatever mode it's in, do : to enter Command mode, and then q! to force a quit (i.e., quit without saving anything), and then try again from the beginning.
It refers to the script itself so does it need to be separate from the script?
Yes.
You might want to check out "ncftp". It would condense your upload command into "ncftpput -u $USER -p $PASSWD $HOST / $FILE", and then you wouldn't need the script at all, just put the whole command into your crontab:
0 2 * * * /usr/bin/time -a ~/output.log ncftpput -u $USER -p $PASSWD $HOST / $FILE
Related
I'm at a loss for what I think may be a simple syntax error. What on line two is causing crontab to throw a "bad minute?" Thanks in advance for the help.
#!/bin/bash
if pgrep -fx "plexdrive mount -v 3 --chunk-check-threads=16 --chunk-
load-threads=16 --chunk-load-ahead=16 --max-chunks=256 /home/username/files/Google/" > /dev/null
then
echo "Plexdrive is running."
else
echo "Plexdrive is not running, starting Plexdrive"
fusermount -uz /home/username/files/Google/
screen -dmS plexdrive plexdrive mount -v 3 --chunk-check-threads=16 --chunk-load-threads=16 --chunk-load-ahead=16 --max-chunks=256 /home/username/files/Google/
fi
exit
The command: pgrep -fx "plexdrive mount -v 3 --chunk-check-threads=16 --chunk-load-threads=16 --chunk-load-ahead=16 --max-chunks=256 /home/username/files/Google/"
runs perfectly fine directly from the command line (returns the process number), so I'm pretty sure I'm just not understanding how to write a logic statement correctly.
Note: The server is remote and I'm merely a user. I have the ability to add to cron but not to services - hence this approach to solving the problem of ensuring that plexdrive (via fuse) always keeps this mount point alive.
You should read up on what a crontab should look like. Not bash source, in any case. It's a configuration file to start (programs and) bash scripts, not to contain bash script.
A crontab line contains the following fields:
minute,
hour,
day of month,
month,
day of week,
each of which specifying when to run the command, and
the command to run.
I.e., if you want your script to run at five minutes after each full hour, and your script is named "my_check_script" (and in PATH), the crontab line should look something like this:
5 * * * * my_check_script
Check the linked documentation for more details.
Following is the entry in the crontab:
MAILTO=abc#gmail.com
45 14 * * * /home/user/simple.sh
I've also done chmod +x on the simple.sh But the crontab does not run, it doesn't even send an email.
pgrep cron shows an Id. I also tried bouncing crond. But no luck!
Could someone please point out the mistake here
The simple.sh script is:
#! /bin/bash
echo hello
Thanks
Since you are doing a echo within the cron job script, you need to capture its output somewhere.
Your shebang and file mode (using chmod +x) are all right, so those aren't the issue here and running without /bin/sh should work fine.
Try using the following to see the output in cron.log file (This runs every minute)
* * * * * /home/user/simple.sh >> /home/user/cron.log
Note that cron jobs run in separate subprocess shell, with reduced environment, so its output won't be visible on your terminal.
Regarding sending of email - you need to have some mail package (like postman, mutt etc) configured for the cron daemon to send out error mails.
Do not use relative paths, but absolute ones. Also, indicate the binary running the script, that is /bin/sh (or whatever coming from which sh):
45 14 * * * /bin/sh /path/to/script/simple.sh
Maybe there shouldn't be a space in line 1 of your .sh script:
#! /bin/bash
to
#!/bin/bash
Although I could see why it would still seem to work from when invoked in an interactive shell (# could merely comment out the rest of the line).
Still, I'd guess at worst it'd merely ignore that line and inherit cron's interpreter of /bin/sh
I very very rarely use Linux and so don't have any experience with bash scripts and cron jobs.
This is in fact my first attempt. So it's probably something really simple to fix.
I have the following:
/etc/cron.d/clear-mixtape-dir.sh
permissions are: 644
#!/bin/bash
# Clears the /tmp/mixtape2 directory
rm -rf "/tmp/mixtape2/"*
My crontab file looks like so:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
*/15 * * * * /etc/cron.d/clear-mixtape-dir.sh >/dev/null 2>&1
I'm trying to execute the .sh script every 15 minutes.
Everything i've found says this should work, but it doesn't.
Does anything like file permissions (on files within /tmp/mixtape2/) matter in this case?
Or perhaps the permissions set on the actual .sh script - maybe they need setting to executable?
Any advice appreciated.
Remove the .sh extension from the script in /etc/cron.d and it will be called.
run-parts ignores files with a period in the name, so the .sh extension is preventing your script from running.
From man cron -
Files must conform to the same naming convention as used by run-parts(8): they must consist solely of upper- and lower-case letters, digits, underscores, and hyphens.
Note: These comments refer to /etc/crontab.
Before doing anything else, which cron are you accessing crontab -e or
su -vim
<your-favorite-editor> /etc/crontab
If you are using crontab -e, then no user field exists in that form of crontab. That might be why you're not running.
In your example, your user field is *. I would make it root or a user that has proper permissions.
Before running this program, I would make a dummy crontab entry that just does
echo "Hello" and runs every minute. Get that to work on which ever crontab you're editing (crontab -e or vim /etc/crontab). Then using that as a template, get your script to run.
Next, see if cron is running:
ps -ef | grep cron
If it is not running, become root and start it by enter
/etc/init.d/cron start (Ubuntu and Red Hat).
You already have a good answer suggesting you add root as the user because of a permissions problem. I'm going to suggest more things to help you debug. I have run into a lot of cron problems over the years.
1) Set the email to a known address, unless you will continually monitor root's email
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/local/bin:/usr/bin
MAILTO=fred#somewhere.com
HOME=/
2) Until everything runs properly, take out the >/dev/null 2>&1 out of your cron entry, so you see the outputs in your email generated after the script runs.
3) Bump */15 down to an interval greater than it takes your script to run -- likr */5, so the script runs more often.
4) I do not know the exact reason, but scripts I run out of cron have to set up their own environments despite being run as that user in cron. This may include steps like cd /home/script-owner and running source .bashrc and calling other script(s) that set environment variables.
*/15 * * * * root /etc/cron.d/clear-mixtape-dir.sh >/dev/null 2>&1
Add user root because your permission seems to be only for root.
Asterisk check script is not running only when run by crontab, but runs by ./script.sh and sh script.sh. Here is the script:
date
asterisk -rx "show channels"
asterisk -rx "zap show channels"
Then I >> into a log file. When I run manually via ./ or sh with >> log.log it works, just not as a crontab listed as
* * * * * /root/script.sh
I have tried adding #!/bash/sh at the top of the script and only the date is shown no matter what I try. I am a noob to bash scripts and I'm trying to learn.
Since feature requests to mark a comment as an answer remain declined, I copy the above solution here.
Have you checked your path? It's almost certainly different when run under cron. (You can set PATH=... in your crontab. From the command line, type "echo $PATH" to see what you're expecting.) It might be more standard to provide full paths to date, asterisk and your log file inside script.sh (e.g., "/bin/date /path/to/asterisk ....") – mjk
I'm trying to setup a crontab I have this in my current job in the current user I'm logged into
* * * * * /CS/day/get_info.sh
get_info.sh is supposed to output a text file every minute and I suspected that it would output a file in the same directory as the script is located but it doesn't.
I've also checked the syslogs to see if I could figure this out.
(user) CMD (/CS/day/get_info.sh)
(user) MAIL (mailed 46 bytes of output but got status 0x0001#012)
Can someone explain to me why this is happening?
Thanks
man cron tells you:
When executing commands, any output is mailed to the owner of the
crontab (or to the user named in the MAILTO environment variable in the
crontab, if such exists). The children copies of cron running these
processes have their name coerced to uppercase, as will be seen in the
syslog and ps output.
So you have to
cd into the appropriate directory yourself (cron will use $HOME)
redirect ANY output to a file of your choice
You can do both things in the crontab. But I recommend to do it in the first lines of the script itself:
#!/bin/bash
cd WHEREEVER_YOU_WANT
exec > YOUR_LOG_FILE 2&>1
The script is run in the home directory of the user and the file should be there as well. If you want it in the same directory as the script, either do a cd in your script or modify your crontab entry:
*/1 19-20 * * * cd /CS/day; /CS/day/get_info.sh
Another common problem with crontab entries is the environment. If the script works correctly in your terminal, try debugging it, when it is run from cron:
40 11 * * * bash -x /CS/day/get_info.sh >/tmp/get_info.sh.log 2>&1
Run it once only with current time, because otherwise you will overwrite your log file every minute.
On my case, I just had to install and configure an smtp client.