I keep on getting error in rc.local [closed] - linux

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have the following script added to my rc.local file
#wait until the internet connection is ready
wget -q --tries=10 --timeout=20 -O - http://google.com > /dev/null
while [ $? -ne 0 ]; do
printf "Waiting for internet connection"
sleep 10;
wget -q --tries=10 --timeout=20 -O - http://google.com > /dev/null;
done
If I am connected to internet everything just works fine but if I am offline I get error
[FAIL] startpar: service(s) returned failure: rc.local ... failed!
What is wrong here and how could I fix it, I want rc.local to wait for internet connection before it continues to another script

As it appears to have solved your problem, this is how I would suggest writing your code:
while ! wget -q --tries=10 --timeout=20 -O - http://google.com > /dev/null; do
echo 'Waiting for internet connection'
sleep 10
done
Remember that [ is not syntax, it is a command whose exit status determines whether your while loop continues or not. You should just test the exit status of the command you are trying to run directly.
As for why this has solved your problem, to be honest I'm not sure. The error message that you have shown isn't really specific enough to indicate where the problem lies and I can't see anything actually wrong with what you did before. Perhaps you should try adding set -xv to your rc.local file to enable debugging.

Related

Process killed after closing terminal SSH [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
I'm trying to clear facebook cache on my server every 2 seconds so i logged in the SSH and i run this command
while true; do sleep 2; curl -F id="http://twd.ma" -F scrape=true -F access_token='token' -F appID=appID https://graph.facebook.com; done &
And every thing worked fine and the cache started to be cleaned every 2 seconds. However, when i close the Terminal SSH the cache stop being cleaned and i think the process is killed, what should i do please?
Your command will stop executing because when you log out, the shell is lost. The '&' means that the script runs in background "as long as the shell is active"
You can do the following:
Write your script into a file, i.e. clearcache.sh and omit the '&'
#!/bin/bash
while true; do
sleep 2
curl -F id="http://twd.ma" -F scrape=true -F access_token='token' -F appID=appID https://graph.facebook.com
done
Write the path to your script into /etc/rc.local
/path/to/clearcache.sh > /dev/null 2&>1 &
The ' >/dev/null 2&>1 means that all output that your script produces will be deleted.
If screen is available to you then you can start a screen session by running screen, run your commands, then press ctrl-a ctrl-d to detach the session.
When you log in later you can issue screen -r to reconnect to the detached session.

Is there a programm in Linux which will execute a command and send an email if it fails? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 7 years ago.
Improve this question
I have a process which is started by Сron like this:
timeout 1h /app/longprocess.sh
Now I want to be notified by email if something goes wrong with it. Imagine this:
notifyme maintainer#example.org timeout 1h /app/longprocess.sh
where notifyme is a supposed command which will send an email to maintainer#example.org with the output of the command in case the command exits with a non-zero status. Is there something like this?
No, but (untested)
notifyme() {
local recipient=$1
shift
output=$( "$#" 2>&1 )
rc=$?
echo "$output"
if [[ $rc -ne 0 ]]; then
mailx -s "Non-zero exit status ($rc) for command: $*" "$recipient" <<< "$output"
fi
}
Use the logical OR operator ||. When || is added to a command, whatever is listed after it will only get executed if the command listed before it returns a non-zero status (that is, if it errors out.) For example, using the code you provided:
timeout 1h /app/longprocess.sh || mail -s "job failed" maintainer#example.org
In the above command, mail -s "job failed" maintainer#example.org will only execute if timeout 1h /app/longprocess.sh is not successful.
Instead of using the || operator as suggested in another answer, I recommend using && and always pinging an external monitoring service. The monitoring service would alert you if a ping is missing. This has the benefit of also getting alerted if your cronjob didn't start up for whatever reason. One such monitor is wdt.io.
Your cronjob would look something like
timeout 1h /app/longprocess.sh && curl somemonitor.com/longprocess

Check a files Modified date and email if it has changed [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I am look for a bash script that will check if a file has been modified in the last hour and email an alert if it has been modified. This script will be used in Solaris and Ubuntu. I am sure it's not hard, but I am not a Linux admin. Can someone please help?
How about this?
#!/bin/bash
[[ -z `find /home/spatel/ -mmin -60` ]]
if [ $? -eq 0 ]
then
echo -e "nothing has changed"
else
mail -s "file has been changed" spatel#example.com
fi
Put this script in hourly cron job
01 * * * * /path/to/myscript
linux supports the inotify command. You use it to monitor file activity - file change, file creation whatever you want, whenever you want.
The find command given above will not work on out-of-the-box solaris. It is fine for linux. You have two options on Solaris:
go to www.sunfreeware.com and download gnu coreutils, which will install gnu find (the above version of find) in /usr/local/bin
write a script that uses the touch command, wait more than 60 minutes then test the file, the only problem is this script runs in the background forever, you can avoid this if you know some perl to generate a timestring suitable for touch -t [time string] to create the file with a time one hour in the past
This is the run forever version:
while true
do
touch dummy
sleep 3615 # 1 hour 15 seconds
[ file_i_want_to_test -nt dummy ] && echo 'file blah changed' |
mailx -s 'file changed' me#myco.com
done

Write a bash script to restart a daemon [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I thought I could just use this related question: How Do I write a bash script to restart a process if it dies. #lhunath had a great answer and told me everything I might do about it was wrong, but I'm restarting a daemon process and if I'm hoping there's something I can do in a single script that works.
my process starts with a kick off script that shows the startup log, but then quits and leaves the process running off the shell:
>sudo ./start
R CMD Rserve --RS-conf /var/FastRWeb/code/rserve.conf --vanilla --no-save
...
Loading required package: FastRWeb
FastRWeb: TRUE
Loading data...
Rserv started in daemon mode.
>
The process is up and running,
ps -ale | grep Rserve
1 S 33 16534 1 0 80 0 - 60022 poll_s ? 00:00:00 Rserve
Is there a simple way to wrap or call the 'start' script from bash and restart when the process dies or is this a case where PID files are actually called for?
Dang - question got closed even after pointing to a very similar question that was not closed on stackoverflow. you guys suck
A very simple way to monitor the program is to use cron: check every minute (or so) if the program still is alive, ./start it otherwise.
As root, invoke crontab -e.
Append a line like this:
* * * * * if ! pidof Rserve 2>&1 >/dev/null; then /full/path/to/start; fi
This method will stay persistent, i.e., it will be executed after a reboot etc. If this is not what you want, move it to a shell script:
#! /bin/bash
# monitor.sh
while true; do
if ! pidof Rserve 2>&1 >/dev/null; then /full/path/to/start; fi
sleep 10
done
This script has to be started manually from the command line, and can be easily stopped with Ctrl-C.
The easiest solution, if you can run the process is NON-daemon mode, is to wrap it in a script.
#!/bin/bash
while (true)
do
xmessage "This is your process. Click OK to kill and respawn"
done
Edit
Many deamons leave a lock file, usually in /var/lock, that contains their PID. This keeps multiple copies of the deamon from running.
Under Linux, it is fairly simple to look throgh /proc and see if that process is still around.
Under other platforms you may need to play games with ps to check for the processes existence.

Test a weekly cron job [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 4 years ago.
Improve this question
I have a #!/bin/bash file in cron.week directory.
Is there a way to test if it works? Can't wait 1 week
I am on Debian 6 with root
Just do what cron does, run the following as root:
run-parts -v /etc/cron.weekly
... or the next one if you receive the "Not a directory: -v" error:
run-parts /etc/cron.weekly -v
Option -v prints the script names before they are run.
A wee bit beyond the scope of your question... but here's what I do.
The "how do I test a cron job?" question is closely connected to "how do I test scripts that run in non-interactive contexts launched by other programs?" In cron, the trigger is some time condition, but lots of other *nix facilities launch scripts or script fragments in non-interactive ways, and often the conditions in which those scripts run contain something unexpected and cause breakage until the bugs are sorted out. (See also: https://stackoverflow.com/a/17805088/237059 )
A general approach to this problem is helpful to have.
One of my favorite techniques is to use a script I wrote called 'crontest'. It launches the target command inside a GNU screen session from within cron, so that you can attach with a separate terminal to see what's going on, interact with the script, even use a debugger.
To set this up, you would use "all stars" in your crontab entry, and specify crontest as the first command on the command line, e.g.:
* * * * * crontest /command/to/be/tested --param1 --param2
So now cron will run your command every minute, but crontest will ensure that only one instance runs at a time. If the command takes time to run, you can do a "screen -x" to attach and watch it run. If the command is a script, you can put a "read" command at the top to make it stop and wait for the screen attachment to complete (hit enter after attaching)
If your command is a bash script, you can do this instead:
* * * * * crontest --bashdb /command/to/be/tested --param1 --param2
Now, if you attach with "screen -x", you'll be facing an interactive bashdb session, and you can step through the code, examine variables, etc.
#!/bin/bash
# crontest
# See https://github.com/Stabledog/crontest for canonical source.
# Test wrapper for cron tasks. The suggested use is:
#
# 1. When adding your cron job, use all 5 stars to make it run every minute
# 2. Wrap the command in crontest
#
#
# Example:
#
# $ crontab -e
# * * * * * /usr/local/bin/crontest $HOME/bin/my-new-script --myparams
#
# Now, cron will run your job every minute, but crontest will only allow one
# instance to run at a time.
#
# crontest always wraps the command in "screen -d -m" if possible, so you can
# use "screen -x" to attach and interact with the job.
#
# If --bashdb is used, the command line will be passed to bashdb. Thus you
# can attach with "screen -x" and debug the remaining command in context.
#
# NOTES:
# - crontest can be used in other contexts, it doesn't have to be a cron job.
# Any place where commands are invoked without an interactive terminal and
# may need to be debugged.
#
# - crontest writes its own stuff to /tmp/crontest.log
#
# - If GNU screen isn't available, neither is --bashdb
#
crontestLog=/tmp/crontest.log
lockfile=$(if [[ -d /var/lock ]]; then echo /var/lock/crontest.lock; else echo /tmp/crontest.lock; fi )
useBashdb=false
useScreen=$( if which screen &>/dev/null; then echo true; else echo false; fi )
innerArgs="$#"
screenBin=$(which screen 2>/dev/null)
function errExit {
echo "[-err-] $#" | tee -a $crontestLog >&2
}
function log {
echo "[-stat-] $#" >> $crontestLog
}
function parseArgs {
while [[ ! -z $1 ]]; do
case $1 in
--bashdb)
if ! $useScreen; then
errExit "--bashdb invalid in crontest because GNU screen not installed"
fi
if ! which bashdb &>/dev/null; then
errExit "--bashdb invalid in crontest: no bashdb on the PATH"
fi
useBashdb=true
;;
--)
shift
innerArgs="$#"
return 0
;;
*)
innerArgs="$#"
return 0
;;
esac
shift
done
}
if [[ -z $sourceMe ]]; then
# Lock the lockfile (no, we do not wish to follow the standard
# advice of wrapping this in a subshell!)
exec 9>$lockfile
flock -n 9 || exit 1
# Zap any old log data:
[[ -f $crontestLog ]] && rm -f $crontestLog
parseArgs "$#"
log "crontest starting at $(date)"
log "Raw command line: $#"
log "Inner args: $#"
log "screenBin: $screenBin"
log "useBashdb: $( if $useBashdb; then echo YES; else echo no; fi )"
log "useScreen: $( if $useScreen; then echo YES; else echo no; fi )"
# Were building a command line.
cmdline=""
# If screen is available, put the task inside a pseudo-terminal
# owned by screen. That allows the developer to do a "screen -x" to
# interact with the running command:
if $useScreen; then
cmdline="$screenBin -D -m "
fi
# If bashdb is installed and --bashdb is specified on the command line,
# pass the command to bashdb. This allows the developer to do a "screen -x" to
# interactively debug a bash shell script:
if $useBashdb; then
cmdline="$cmdline $(which bashdb) "
fi
# Finally, append the target command and params:
cmdline="$cmdline $innerArgs"
log "cmdline: $cmdline"
# And run the whole schlock:
$cmdline
res=$?
log "Command result: $res"
echo "[-result-] $(if [[ $res -eq 0 ]]; then echo ok; else echo fail; fi)" >> $crontestLog
# Release the lock:
9<&-
fi
After messing about with some stuff in cron which wasn't instantly compatible I found that the following approach was nice for debugging:
crontab -e
* * * * * /path/to/prog var1 var2 &>>/tmp/cron_debug_log.log
This will run the task once a minute and you can simply look in the /tmp/cron_debug_log.log file to figure out what is going on.
It is not exactly the "fire job" you might be looking for, but this helped me a lot when debugging a script that didn't work in cron at first.
I'd use a lock file and then set the cron job to run every minute. (use crontab -e and * * * * * /path/to/job) That way you can just keep editing the files and each minute they'll be tested out. Additionally, you can stop the cronjob by just touching the lock file.
#!/bin/sh
if [ -e /tmp/cronlock ]
then
echo "cronjob locked"
exit 1
fi
touch /tmp/cronlock
<...do your regular cron here ....>
rm -f /tmp/cronlock
What about putting it into cron.hourly, waiting until the next run of hourly cron jobs, then removing it? That would run it once within an hour, and in the cron environment. You can also run ./your_script, but that won't have the same environment as under cron.
Aside from that you can also use:
http://pypi.python.org/pypi/cronwrap
to wrap up your cron to send you an email upon success or failure.
None of these answers fit my specific situation, which was that I wanted to run one specific cron job, just once, and run it immediately.
I'm on a Ubuntu server, and I use cPanel to setup my cron jobs.
I simply wrote down my current settings, and then edited them to be one minute from now. When I fixed another bug, I just edited it again to one minute from now. And when I was all done, I just reset the settings back to how they were before.
Example: It's 4:34pm right now, so I put 35 16 * * *, for it to run at 16:35.
It worked like a charm, and the most I ever had to wait was a little less than one minute.
I thought this was a better option than some of the other answers because I didn't want to run all of my weekly crons, and I didn't want the job to run every minute. It takes me a few minutes to fix whatever the issues were before I'm ready to test it again. Hopefully this helps someone.
The solution I am using is as follows:
Edit crontab(use command :crontab -e) to run the job as frequently
as needed (every 1 minute or 5 minutes)
Modify the shell script which should be executed using cron to prints the output into some file (e.g: echo "Working fine" >>
output.txt)
Check the output.txt file using the command : tail -f output.txt, which will print the latest additions into this file, and thus you can track the execution of the script
I normally test by running the job i created like this:
It is easier to use two terminals to do this.
run job:
#./jobname.sh
go to:
#/var/log and run
run the following:
#tailf /var/log/cron
This allows me to see the cron logs update in real time. You can also review the log after you run it, I prefer watching in real time.
Here is an example of a simple cron job. Running a yum update...
#!/bin/bash
YUM=/usr/bin/yum
$YUM -y -R 120 -d 0 -e 0 update yum
$YUM -y -R 10 -e 0 -d 0 update
Here is the breakdown:
First command will update yum itself and next will apply system updates.
-R 120 : Sets the maximum amount of time yum will wait before performing a command
-e 0 : Sets the error level to 0 (range 0 - 10). 0 means print only critical errors about which you must be told.
-d 0 : Sets the debugging level to 0 - turns up or down the amount of things that are printed. (range: 0 - 10).
-y : Assume yes; assume that the answer to any question which would be asked is yes
After I built the cron job I ran the below command to make my job executable.
#chmod +x /etc/cron.daily/jobname.sh
Hope this helps,
Dorlack
sudo run-parts --test /var/spool/cron/crontabs/
files in that crontabs/ directory needs to be executable by owner - octal 700
source: man cron and NNRooth's
I'm using Webmin because its a productivity gem for someone who finds command line administration a bit daunting and impenetrable.
There is a "Save and Run Now" button in the "System > Scheduled Cron Jobs > Edit Cron Job" web interface.
It displays the output of the command and is exactly what I needed.

Resources