this is my first question (in that forum) so please be patient ... ;-)
To the problem:
I'm trying to run a binary on an raspi that crashes by chance once in a few hours. As the binary gives its output usually to stdout, I'm trying to use it with screen and pipe its output to a file. Doing so, I've written a small wrapper script which is called by cron every five minutes. My idea was, that, if the output file don't changes over a certain period, than the process is killed and restarted.
Here 's my /etc/crontab:
*/5 * * * * pi bash /home/pi/myscript.sh >/dev/null 2>/dev/null
Here 's the myscript:
#!/bin/bash
# Input file
FILE=/home/pi/output.txt
# How many seconds before file is deemed "older"
OLDTIME=300
# Get current and file times
CURTIME=$(date +%s)
FILETIME=$(stat $FILE -c %Y)
TIMEDIFF=$(expr $CURTIME - $FILETIME)
# Check if file older
if [ $TIMEDIFF -gt $OLDTIME ]; then
#echo "File is older, do stuff here"
bash /home/pi/check_myscript_is_running.sh
fi
Here 's the script that checks:
#!/bin/bash
case "$(pidof processname | wc -w)" in
0) echo "Restarting process: $(date)" >> ~/output.txt
screen -dm /home/pi/binary -l output.txt &
;;
1) # all ok
;;
*) echo "Removed double process: $(date)" >> ~output.txt
kill $(pidof process | awk '{print $1}')
;;
esac
But obviously the last script doesn't start the process anew and I'm getting mails from the cron:
From pi#raspberrypi Fri Jul 01 16:42:25 2016
Return-path: <pi#raspberrypi>
Envelope-to: pi#raspberrypi
Delivery-date: Fri, 01 Jul 2016 16:42:25 +0200
Received: from pi by raspberrypi with local (Exim 4.84_2)
(envelope-from <pi#raspberrypi>)
id 1bIzeD-00007c-0A
for pi#raspberrypi; Fri, 01 Jul 2016 16:42:25 +0200
From: root#raspberrypi (Cron Daemon)
To: pi#raspberrypi
Subject: Cron <pi#raspberrypi> pi /home/pi/startprocess.sh
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/pi>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=pi>
Message-Id: <E1bIzeD-00007c-0A#raspberrypi>
Date: Fri, 01 Jul 2016 16:42:25 +0200
/bin/sh: 1: pi: not found
I don't have a script startprocess.sh and I thought that with the output pipe the mails would be suppressed ...
But the main question is: Why is the script that should restart the process if the output file has'nt changed for five minutes not running ?
Cheers and regards,
JD.
If I understand right: In some environments the cron PATH is not set, so calling up pi in your crontab leads to the error mail you get.
Try to fully qualify your script call with an absolute path, e.g. like this:
*/5 * * * * /path/to/script/pi /usr/bin/bash /home/pi/myscript.sh >/dev/null 2>/dev/null
Related
I have a script, when i write it in /etc/crontab it works, but it does not work in the following conditions:
crontab -l > wakeup
echo "20 15 * * thu root CALLERID=755 LIST=4001 FILE=hello-world /bin/sh /usr/local/bin/asterisk_wakeup_call.sh" >> wakeup
crontab wakeup
rm wakeup
asterisk_wakeup_call.sh
for element in $LIST
do
/usr/bin/touch /tmp/$element.call
/bin/cat >> /tmp/$element.call <<-EOF
Channel: SIP/${element}
Application: Playback
Data:${FILE}
Callerid: ${CALLERID}
EOF
/bin/mv /tmp/$element.call /var/spool/asterisk/
/bin/mv /var/spool/asterisk/$element.call /var/spool/asterisk/outgoing
done
I should add:
The cron daemon is running
The files have permission
please help me to find the mistake.
I need to list all the logged in users along with the date and time of log in. How can I do that using shell script?
#!/bin/bash
cat > log.log << EOF1
how to replace the bash command 'w' in here
EOF1
This is written for Mac, not tried in a linux machine.
write this to login.sh
#!/bin/bash
last |grep "logged in" > ./login.log
touch login.log
run ./login.sh
Then cat login.log you can see
userA ttys001 Sun Jun 9 12:07 still logged in
userB ttys000 Sun Jun 9 11:53 still logged in
userC console Sun Jun 9 11:49 still logged in
You can use only w > log.log like oguz ismail writes, or you can write the output of w into a variable and display this variable in the here-document.
#!/bin/bash
w_content=$(w)
cat > log <<EOF
Headline
$w_content
Footer
EOF
Kindly check below script, It will work your demand
#!/bin/bash
a=$(echo -e "current date and time :- \n $(date)\n"
echo -e "All logged in Users with details :- \n $(who)\n "
echo -e "Server uptime :-\n $(uptime |awk -F ',' '{print $1}') \n"
echo -e "Script running entries are logged in log file /var/log/sh.log")
echo "$a" && echo "$a" >> /var/log/sh.log 2>&1
I am using /bin/script to capture the output of a command and preserve the colors and formatting. Using subshell and assigning to variable does not always work well. E.g.,:
foo="$( ls --color 2>&1 )"
I can use /bin/script to capture stdout:
$ script -qc "echo foo" >& /dev/null && cat typescript
Script started on Mon 06 Nov 2017 10:40:40 PM PST
foo
I can use /bin/script to capture stderr (ls of non-existent directory goes to stderr):
$ script -qc "ls vxzcvcxvc" >& /dev/null && cat typescript
Script started on Mon 06 Nov 2017 10:38:17 PM PST
ls: cannot access vxzcvcxvc: No such file or directory
My problem arises when the script run inside /bin/script mucks with file descriptors.
I am not able to use /bin/script to capture redirected stderr:
$ script -qc "ls vxzcvcxvc 2>&1" >& /dev/null && cat typescript
Script started on Mon 06 Nov 2017 10:47:13 PM PST
I have tried other ways as well:
$ script -qc "echo foo1 && >&2 echo foo2 && echo foo3" >& /dev/null && cat typescript
Script started on Mon 06 Nov 2017 10:46:09 PM PST
foo1
foo3
I assume /bin/script is doing its own file descriptor magic (redirecting output to file), so I am left wondering what to do if the script I am calling does its own redirection.
Tangential question: The primary culprit is a logging line that does
printf "${1}" 1>&2
in order to print logging to stderr. Is there a way to output to stderr without mucking with file descriptors (assuming this is the reason /bin/script fails to pick it up)?
I will like to write (using bash) something like
while no_user_key_pressed
{
do_something....
}
There are a few options using C++, Java, ncurses and others o/s specific. I want a simple bash portable function.
^c interrupt should be used to kill the remaining code. Imagine something like: 'Press any key to stop test'
You can use a small timeout on read -t.
The drawback is that the user must press < RETURN >, not "any key".
For example:
while ! read -t 0.01
do
echo -en "$(date)\r"
done
echo "User pressed: $REPLY"
Tested on bash 3.2 (OS X)
The ! is because read returns a failure (false) if the timeout expires.
You can trap Ctrl-c in a way that does not kill the remaining code:
$ cat test.sh
#!/usr/bin/env bash
trap 'break' INT
while true
do
date
sleep 1
done
echo done
$ ./test.sh
Tue 28 Jun 12:01:22 UTC 2016
Tue 28 Jun 12:01:23 UTC 2016
Tue 28 Jun 12:01:24 UTC 2016
^Cdone
update:
when I echo $res in the script below, I get the following, I guess it's because the script itself contains the word searchd!! so at the very instant that the cronjob process gets executed, $res becomes empty!
I renamed the script, problem solved!
root 10769 7177 0 23:31 pts/1 00:00:00 /bin/bash /home/scripts/monitor_searchd.sh root 10770 10769 0 23:31 pts/1 00:00:00 /bin/bash /home/scripts/monitor_searchd.sh
original problem:
I have a shell script that works when I invoke it in the shell, but when putting in crontab in the following way, it doesn't work(not sending an email). The strange thing is that cron log shows that the process is getting ran every minute!
*/1 * * * * root /home/scripts/monitor_searchd.sh
here's the script:
process="java"
res="`ps -ef|grep $process|grep -v grep`"
if [ ! -n "$res" ]; then
echo "$process is down!" | mail -s "$process is down" xxx#gmail.com
fi
cron log
CROND[7370]: (root) CMD (/home/scripts/monitor_searchd.sh)
Can you please add:
echo "$process is down!" >> /tmp/monitor_searcd.log
before the line with mail? It could help localize the problem.
And pair of small remarks:
Please add
#!/bin/bash
to the first line of the script.
Change
[ ! -n "$res" ]
to
[ -z "$res" ]