Send bash script into background on start - bash

with all the kind replies to my last question I have been able to create a small script to check temperatures on my NAS but now I am struggling on sending it to the background. When I try to start my script with
sh temp_check.sh start
I get an error pointing to this line
$0 background &
and I can't figure out why :/
This is my whole script
#!/ffp/bin/sh
#
#check CPU and HDD temperature and shutdown if too hot
#Settings
cpu_high=60
hdd_high=50
NAME="temp_check"
PIDFILE="/var/run/$NAME.pid"
Background() {
echo $$ >$PIDFILE
exec >/dev/null 2>&1
trap "rm -f $PIDFILE ; exit 0" INT TERM EXIT
while true; do
STATE=$(hdparm -C /dev/sda1 | grep "drive state" | awk '{print $4}')
if [ "$STATE" = "active/idle" ]; then
hdd_temp=$(/usr/local/zy-pkgs/bin/smartctl -A -d marvell /dev/sda | grep 194 | cut -d: -f3 | awk '{print $10}')
cpu_temp=$(i2cget -y 0x0 0x0a 0x07)
printf -v cpu_res "%d" "$cpu_temp"
if [[ $cpu_res -lt $cpu_high && $hdd_temp -lt $hdd_high ]]; then
#echo "CPU und HDD Temperaturen in Ordnung"
sleep 30
else
halt
fi
else
cpu_temp=$(i2cget -y 0x0 0x0a 0x07)
printf -v cpu_res "%d" "$cpu_temp"
if [ $cpu_res -lt $cpu_high ]; then
#echo "CPU Temperatur in Ordnung - HDD im Standby Modus"
sleep 30
else
halt
fi
fi
done
}
case $1 in
start)
[ -f $PIDFILE ] && [ -f /proc/` cat $PIDFILE `/cmdline ] && echo "already running. Aborting." && exit 1
$0 background &
echo "Starting $NAME..."
;;
stop)
kill -9 ` cat $PIDFILE ` >/dev/null 2>&1
echo "Stopping $NAME ` cat $PIDFILE ` "
;;
status)
[ -f $PIDFILE ] && [ -f /proc/` cat $PIDFILE `/cmdline ] && echo "running as ` cat $PIDFILE ` " && exit 0
echo "not running"
;;
background)
Background
;;
*)
echo "use $0 [ start | stop | status ]"
;;
esac
Any help is appreciated
Cheers
Moritz

One possible error is, that the script is not executable. If this is the case, you can either fix the line to
/bin/sh $0 background &
or make the script executable with
chmod a+x temp_check.sh

maybe it helps, if you change your Background() function to something like
Background()
{ (
...
) &
}
and just call Background in your "start". That's much simpler.

Related

I'm trying to find a alternative for timeout in bash 3

I have tried a method using timeout to identify and exit server comes to RUNNING state or else exit watching for RUNNING state at the timeout value, unfortunately one of the server has bash version 3 and doesn't support time out.
timeout 300s grep -q 'Server state changed to RUNNING' <(tail -f AdminServer.out)
if [ $? != 0];then
printf "\n===> unable to bring up the server.please check\n"
else
printf "\n===> server came to RUNNING state\n"
fi
I have tried the following but wasn't able to exit when the log is appeared
( cmdpid=$BASHPID; (sleep 60; kill $cmdpid) & exec `grep -q 'Server state changed to RUNNING' <(tail -f AdminServer.out)`)
but it first give command line substitution error for grep -q 'Server state changed to RUNNING' <(tail -f AdminServer.out) and then gives error for kill usage like below(seems the kill is not working) ,
kill: usage: kill [-s sigspec | etc....
I'm not in a position to upgrade the bash version of the server unfortunately, any guidance for this highly appreciated .Thank you!!
*server: suse distribution 2.6.32.12-0.7-default
Consider to try something like this:
data=$(
tail -f AdminServer.out & pid=$!
till=$[SECONDS+300]
while ((SECONDS<till)); do :; done
kill -9 $pid
)
grep -q 'Server state changed to RUNNING' <<< "$data" \
&& printf "\n===> server came to RUNNING state\n" \
|| printf "\n===> unable to bring up the server.please check\n"
When I was young... on OSF1, DEC Alpha, SPARC...
without timeout command, without <(...) or <<< operators...
I'm actively waiting...
File: timeout.sh
#! /bin/bash
PID="$1"
SEC="$2"
FILE="$3"
DATE_REF=$(date +%s)
DATE_MAX=$(( DATE_REF + ${SEC} ))
while ps -p "${PID}" >/dev/null 2>&1 && [[ $(date +%s) -lt ${DATE_MAX} ]] && ! grep OK "${FILE}" >/dev/null 2>&1; do
sleep 1
done
if grep OK "${FILE}" >/dev/null 2>&1; then
RET=0
else
RET=1
fi
if ps -p "${PID}" >/dev/null 2>&1; then
kill -9 "${PID}"
fi
rm -f "${FILE}"
exit $RET
Used like that:
nb_seconds_to_wait=5
tail -f my_log_file | grep -m 1 my_token_to_search && echo "OK" > my_flag_file &
timeout.sh $! nb_seconds_to_wait my_flag_file
if [[ $? -eq 0 ]]; then
echo "Found"
else
echo "Not found"
fi
I have tried again and came up with the following, am I doing anything harmful here?
( cmdpid=$BASHPID; ( sleep 10; if ps -p $cmdpid > /dev/null; then kill $cmdpid > /dev/null;fi ) & while `tail -f -n0 AdminServer.out | grep -q RUNNING`; do exit 0;done )
echo "proceeding with the rest of commands the previous command status is $?"

Daemon script - sh: unknown operand; arithmetic syntax error

I might be blind, but I can't find the errors my script got, maybe you guys got better eyes than me :). I use a busybox compiled linux on a embedded system, Kernel 4.18.0. I found the base script here: Gist-Template
the following error is at "start":
./daemon: line 195: arithmetic syntax error
when I try "stop" these messages appear, but i dont see a unknown operand at line 0:
sh: 0: unknown operand
* Stopping Monitoring
my script:
#!/bin/sh
daemonName="Monitoring"
pidDir="."
pidFile="$pidDir/$daemonName.pid"
pidFile="$daemonName.pid"
logDir="."
# To use a dated log file.
# logFile="$logDir/$daemonName-"`date +"%Y-%m-%d"`".log"
# To use a regular log file.
logFile="$logDir/$daemonName.log"
# Log maxsize in KB
logMaxSize=1024 # 1mb
runInterval=300 # In seconds
doCommands() {
# This is where you put all the commands for the daemon.
echo "Running commands."
}
############################################################
# Below are the command functions
############################################################
hw_temp() {
cpu_temp=$(sensors|grep CPU|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
env_temp=$(sensors|grep ENV|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
pcb_temp=$(sensors|grep PCB|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
echo "$cpu_temp $env_temp $pcb_temp" >> /opt/monitoring/bla
}
############################################################
# Below is the skeleton functionality of the daemon.
############################################################
myPid=`echo $$`
setupDaemon() {
# Make sure that the directories work.
if [ ! -d "$pidDir" ]; then
mkdir "$pidDir"
fi
if [ ! -d "$logDir" ]; then
mkdir "$logDir"
fi
if [ ! -f "$logFile" ]; then
touch "$logFile"
else
# Check to see if we need to rotate the logs.
size=$((`ls -l "$logFile" | cut -d " " -f 8`/1024))
if [[ $size -gt $logMaxSize ]]; then
mv $logFile "$logFile.old"
touch "$logFile"
fi
fi
}
startDaemon() {
# Start the daemon.
setupDaemon # Make sure the directories are there.
if [[ `checkDaemon` = 1 ]]; then
echo " * \033[31;5;148mError\033[39m: $daemonName is already running."
exit 1
fi
echo " * Starting $daemonName with PID: $myPid."
echo "$myPid" > "$pidFile"
log '*** '`date +"%Y-%m-%d"`": Starting up $daemonName."
# Start the loop.
loop
}
stopDaemon() {
# Stop the daemon.
if [[ `checkDaemon` -eq 0 ]]; then
echo " * \033[31;5;148mError\033[39m: $daemonName is not running."
exit 1
fi
echo " * Stopping $daemonName"
log '*** '`date +"%Y-%m-%d"`": $daemonName stopped."
if [[ ! -z `cat $pidFile` ]]; then
kill -9 `cat "$pidFile"` &> /dev/null
fi
}
statusDaemon() {
# Query and return whether the daemon is running.
if [[ `checkDaemon` -eq 1 ]]; then
echo " * $daemonName is running."
else
echo " * $daemonName isn't running."
fi
exit 0
}
restartDaemon() {
# Restart the daemon.
if [[ `checkDaemon` = 0 ]]; then
# Can't restart it if it isn't running.
echo "$daemonName isn't running."
exit 1
fi
stopDaemon
startDaemon
}
checkDaemon() {
# Check to see if the daemon is running.
# This is a different function than statusDaemon
# so that we can use it other functions.
if [ -z "$oldPid" ]; then
return 0
elif [[ `ps aux | grep "$oldPid" | grep "$daemonName" | grep -v grep` > /dev/null ]]; then
if [ -f "$pidFile" ]; then
if [[ `cat "$pidFile"` = "$oldPid" ]]; then
# Daemon is running.
# echo 1
return 1
else
# Daemon isn't running.
return 0
fi
fi
elif [[ `ps aux | grep "$daemonName" | grep -v grep | grep -v "$myPid" | grep -v "0:00.00"` > /dev/null ]]; then
# Daemon is running but without the correct PID. Restart it.
log '*** '`date +"%Y-%m-%d"`": $daemonName running with invalid PID; restarting."
restartDaemon
return 1
else
# Daemon not running.
return 0
fi
return 1
}
loop() {
# This is the loop.
now=`date +%s`
if [ -z $last ]; then
last=`date +%s`
fi
# Do everything you need the daemon to do.
doCommands
# Check to see how long we actually need to sleep for. If we want this to run
# once a minute and it's taken more than a minute, then we should just run it
# anyway.
last=`date +%s`
# Set the sleep interval
if [[ ! $((now-last+runInterval+1)) -lt $((runInterval)) ]]; then
sleep $((now-last+runInterval))
fi
# Startover
loop
}
log() {
# Generic log function.
echo "$1" >> "$logFile"
}
###############################################################
# Parse the command.
###############################################################
if [ -f "$pidFile" ]; then
oldPid=`cat "$pidFile"`
fi
checkDaemon
case "$1" in
start)
startDaemon
;;
stop)
stopDaemon
;;
status)
statusDaemon
;;
restart)
restartDaemon
;;
*)
echo "Error: usage $0 { start | stop | restart | status }"
exit 1
esac
exit 0

Where is the 2 minutes setting in the knoppix-halt file?

According to the knoppix-halt file, it mention that
Please remove CD, close cdrom drive and hit return [2 minutes]
I look through the file so many times but still could not find the 2 minutes setting. I know that sleep X will sleep for X seconds while usleep X will sleep for microsecond. So, I went to look for sleep 120 and usleep 120000000 but did not find any.
So, can someone enlighten me why the message say 2 minutes but I could not find inside the script file?
#!/bin/busybox sh
# This script does:
# - Kill all processes
# - umount/sync filesystems (and freeing loopback files)
# - Eventually eject CD-Rom (autoeject turned on)
PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/bin
export PATH
cd /
NORMAL="\033[0;39m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
MAGENTA="\033[1;35m"
CYAN="\033[1;36m"
WHITE="\033[1;37m"
GRAY="\033[1;38m"
[ -r /etc/default/locale ] && . /etc/default/locale
[ -r /etc/sysconfig/i18n ] && . /etc/sysconfig/i18n
case "$LANG" in
de*)
EJECTMSG="Bitte CD entfernen, Laufwerk schließen und Eingabetaste drücken [2 Minuten]"
COMPLETEMSG="Shutdown beendet."
;;
*)
EJECTMSG="Please remove CD, close cdrom drive and hit return [2 minutes]."
COMPLETEMSG="Shutdown complete."
;;
esac
# Read in boot parameters
read CMDLINE </proc/cmdline 2>/dev/null
echo 0 >/proc/sys/kernel/printk
PROGRESSBAR="/tmp/knoppix-halt.progress"
progress(){
local black="\033[0;0m \033[0m"
local p
local count=0
echo -n -e "\033[1mSystem Shutdown... \033[42;32m \033[0m"
type usleep >/dev/null 2>&1 && sleep="usleep 100000" || sleep="sleep 1"
[ -r "$PROGRESSBAR" ] && rm -f "$PROGRESSBAR" 2>/dev/null
touch "$PROGRESSBAR"
while [ -r "$PROGRESSBAR" ]; do
if [ "$count" -ge 55 ]; then
for p in "/" "-" "\\" "|"; do
echo -n -e "\b${p}"
$sleep
[ -r "$PROGRESSBAR" ] || break
done
else
echo -n -e "\b$black\b"
$sleep
fi
let count++
done
echo -e "\r\033[J\033[1m${COMPLETEMSG}\033[0m"
}
# Return 0 if there is active swap, but
# enough memory available to call swapoff, 1 otherwise.
checkswap(){
local free=0 buffers=0 cache=0 swaptotal=0 swapfree=0 info amount kb
while read info amount kb; do
case "$info" in
MemFree:) free="$amount";;
Buffers:) buffers="$amount";;
Cached:) cached="$amount";;
SwapTotal:) swaptotal="$amount";;
SwapFree:) swapfree="$amount";;
esac
done </proc/meminfo
avail="$((free + buffers + cached))"
swapused="$((swaptotal - swapfree))"
if [ "$swaptotal" -gt 0 -a "$avail" -gt "$swapused" ] >/dev/null 2>&1; then
return 0
else
return 1
fi
}
OMIT=""
for i in $(pidof ntfs-3g aufs aufsd fuse fuseblk cloop0 cloop1 cloop2 cloop3 cloop4 cloop5 cloop6 cloop7 klogd syslogd); do OMIT="$OMIT -o $i"; done 2>/dev/null
killall5 -15 $OMIT; sleep 2
case "$CMDLINE" in *nosound*|*noaudio*|*nostartsound*) true ;; *)
# Play sound if soundcard is alive and soundfile present
# (also giving running programs some more time to terminate)
[ -r /usr/share/sounds/shutdown.ogg -a -f /proc/asound/pcm ] && \
type -p ogg123 >/dev/null 2>&1 && \
{ ogg123 -q --audio-buffers 4096 /usr/share/sounds/shutdown.ogg 2>/dev/null & sleep 2; }
;;
esac
# Clean console i/o
exec >/dev/console 2>&1 </dev/console
stty sane
echo -n -e "\r\033[K"
# echo -e "\033[H\033[J"
# Start progress bar
[ -n "$DEBUG" ] || progress &
# Check which device is mounted as /mnt-system
system="$(awk '/ \/mnt-system /{print $1;exit 0}' /proc/mounts 2>/dev/null)"
# noprompt or noeject option?
NOPROMPT="yes"; NOEJECT="yes"
case "$CMDLINE" in
*noprompt*) ;;
*) # Check if we need to wait for /mnt-system to be ejected.
if [ -n "$system" ]; then
for cdrom in $(awk '/drive name:/{print $NF}' /proc/sys/dev/cdrom*/info 2>/dev/null); do
[ "$system" = "/dev/$cdrom" ] && { NOEJECT=""; NOPROMPT=""; break; }
done
fi
;;
esac
case "$CMDLINE" in *noeject*) NOEJECT="yes" ;; esac
DEBUG=""
case "$CMDLINE" in *\ debug\ *|*BOOT_IMAGE=debug*) DEBUG="yes" ;; esac
# turn off swap, then unmount file systems.
# should free ramdisk space first, check
if checkswap; then
swapoff -a >/dev/null 2>&1
fi
# Shut down network, if no nfs mounted
# Actually... Not needed.
# grep -q ' nfs' /proc/mounts || ifdown -a >/dev/null 2>&1
# Kill remaining processes
killall5 -9 $OMIT
# Turn on autoeject of CD-Roms
if [ -z "$NOEJECT" ]; then
for dev in /proc/sys/dev/cdrom*/lock; do [ -f "$dev" ] && echo 0 > "$dev"; done
for dev in /proc/sys/dev/cdrom*/autoeject; do [ -f "$dev" ] && echo 1 > "$dev"; done
fi
# Try to sync for 30 seconds max.
sync &
SYNCPID="$!"
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
sleep 2
[ -d /proc/"$SYNCPID" ] || break
done
# Free modules
# Do we need to unload modules at all?
#
#while read module relax; do
# case "$module" in
# *eeepc*|*_laptop*) true ;; # Unloading eeepc_laptop disables WLAN in the BIOS. Why?
# *) rmmod "$module" ;;
# esac
#done </proc/modules >/dev/null 2>&1
# Remove all automatically added entries from /etc/fstab
sed -i -e "/^# Added by KNOPPIX/{N;d}" /etc/fstab
# Force sync, then umount.
tac /proc/mounts | while read d m f relax; do
[ -d "$d" ] || continue
case "$f" in tmpfs|proc|sysfs|devpts|usbfs|aufs) ;; *)
case "$f" in rootfs|nfs*) ;; *) blockdev --flushbufs "$d" 2>/dev/null; umount -l "$m" 2>/dev/null ;; esac
case "$d" in /dev/mapper/*) /sbin/dmsetup --force remove "$d" 2>/dev/null ;; esac
;;
esac
done
# We have to use /bin/umount here, since busybox umount does not accept -t no*
# /bin/umount -t notmpfs,noproc,nosysfs,nousbfs,norootfs,noaufs,nonfs -adrf 2>/dev/null
# Free loopback devices which may have been used but not mounted.
for i in /dev/loop* /dev/loop/*; do [ -b "$i" ] && losetup -d "$i" 2>/dev/null; done
# End progress bar
[ -f "$PROGRESSBAR" ] && { rm -f "$PROGRESSBAR" 2>/dev/null; sleep 1; }
sleep 1
echo ""
# Mount boot medium read-only
umount -r /mnt-system 2>/dev/null
# And finally, umount
umount -l /mnt-system 2>/dev/null
# (Harddisk-installation only): mount / read-only
umount -r / 2>/dev/null
# Enable sysrq feature (just in case someone has turned it off)
# echo -n -e '\033[s\033[8m' # No output, save cursor position
echo 1 > /proc/sys/kernel/sysrq
echo s > /proc/sysrq-trigger 2>/dev/null & # emergency sync
sleep 1
echo u > /proc/sysrq-trigger 2>/dev/null & # emergency remount-ro
sleep 1
# echo -n -e '\033[28m\033[u' # re-enable output, restore cursor position
# pre-load poweroff+halt+eject if not included in this shell
poweroff --help >/dev/null 2>&1
reboot --help >/dev/null 2>&1
eject --help >/dev/null 2>&1
if [ -z "$NOEJECT" ]; then
( eject -s $system >/dev/null 2>&1 || eject $system >/dev/null 2>&1 & )
if [ -z "$NOPROMPT" ]; then
echo -n -e "${CYAN}${EJECTMSG}${NORMAL} "
read -t 120 a
fi
fi
case "$0" in
*halt|*poweroff) { poweroff -f 2>/dev/null & sleep 8; } || echo o > /proc/sysrq-trigger 2>/dev/null ;;
*) { reboot -f 2>/dev/null & sleep 8; } || echo b > /proc/sysrq-trigger 2>/dev/null ;;
esac
# Should never be reached.
sleep 2
echo -n -e "\033[1mYou can now turn off your computer.\033[0m"
halt -f
sleep 1337
At the bottom it says:
echo -n -e "${CYAN}${EJECTMSG}${NORMAL} "
read -t 120 a
This writes the message, and then waits up to 120 seconds for you to press return.

bash: running cURLs in parallel slower than one after another

We have to cache quite a big database of data after each upload, so we created a bash script that should handle it for us. The script should start 4 paralel curls to the site and once they're done, start the next one from the URL list we store in the file.
In theory everything works ok, and the concept works if we run the run 4 processes from our local machines to the target site.
If i set the MAX_NPROC=1 the curl takes as long as it would if the browser hits the URL
i.e. 20s
If I set the MAX_NPROC=2 the time request took, triples.
Am I missing something? Is that an apache setting that is slowing us down? or is this a secret cURL setting that I'm missing?
Any help will be appreciated. Please find the bash script below
#!/bin/bash
if [[ -z $2 ]]; then
MAX_NPROC=4 # default
else
MAX_NPROC=$2
fi
if [[ -z $1 ]]; then
echo "File with URLs is missing"
exit
fi;
NUM=0
QUEUE=""
DATA=""
URL=""
declare -a URL_ARRAY
declare -a TIME_ARRAY
ERROR_LOG=""
function queue {
QUEUE="$QUEUE $1"
NUM=$(($NUM+1))
}
function regeneratequeue {
OLDREQUEUE=$QUEUE
echo "OLDREQUEUE:$OLDREQUEUE"
QUEUE=""
NUM=0
for PID in $OLDREQUEUE
do
process_count=`ps ax | awk '{print $1 }' | grep -c "^${PID}$"`
if [ $process_count -eq 1 ] ; then
QUEUE="$QUEUE $PID"
NUM=$(($NUM+1))
fi
done
}
function checkqueue {
OLDCHQUEUE=$QUEUE
for PID in $OLDCHQUEUE
do
process_count=`ps ax | awk '{print $1 }' | grep -c "^${PID}$"`
if [ $process_count -eq 0 ] ; then
wait $PID
my_status=$?
if [[ $my_status -ne 0 ]]
then
echo "`date` $my_status ${URL_ARRAY[$PID]}" >> $ERROR_LOG
fi
current_time=`date +%s`
old_time=${TIME_ARRAY[$PID]}
time_difference=$(expr $current_time - $old_time)
echo "`date` ${URL_ARRAY[$PID]} END ($time_difference seconds)" >> $REVERSE_LOG
#unset TIME_ARRAY[$PID]
#unset URL_ARRAY[$PID]
regeneratequeue # at least one PID has finished
break
fi
done
}
REVERSE_LOG="$1.rvrs"
ERROR_LOG="$1.error"
echo "Cache STARTED at `date`" > $REVERSE_LOG
echo "" > ERROR_LOG
while read line; do
# create the command to be run
DATA="username=user#server.com&password=password"
URL=$line
CMD=$(curl --data "${DATA}" -s -o /dev/null --url "${URL}")
echo "Command: ${CMD}"
# Run the command
$CMD &
# Get PID for process
PID=$!
queue $PID;
URL_ARRAY[$PID]=$URL;
TIME_ARRAY[$PID]=`date +%s`
while [ $NUM -ge $MAX_NPROC ]; do
checkqueue
sleep 0.4
done
done < $1
echo "Cache FINISHED at `date`" >> $REVERSE_LOG
exit
The network is almost always the bottleneck. Spawning more connections usually makes it slower.
You can try to see if parallel'izing it will do you any good by spawning several
time curl ...... &

Bash script to check running process [duplicate]

This question already has answers here:
Linux Script to check if process is running and act on the result
(8 answers)
Closed 5 years ago.
I wrote a bash-script to check if a process is running. It doesn't work since the ps command always returns exit code 1. When I run the ps command from the command-line, the $? is correctly set, but within the script it is always 1. Any idea?
#!/bin/bash
SERVICE=$1
ps -a | grep -v grep | grep $1 > /dev/null
result=$?
echo "exit code: ${result}"
if [ "${result}" -eq "0" ] ; then
echo "`date`: $SERVICE service running, everything is fine"
else
echo "`date`: $SERVICE is not running"
fi
Bash version: GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
There are a few really simple methods:
pgrep procname && echo Running
pgrep procname || echo Not running
killall -q -0 procname && echo Running
pidof procname && echo Running
This trick works for me. Hope this could help you. Let's save the followings as checkRunningProcess.sh
#!/bin/bash
ps_out=`ps -ef | grep $1 | grep -v 'grep' | grep -v $0`
result=$(echo $ps_out | grep "$1")
if [[ "$result" != "" ]];then
echo "Running"
else
echo "Not Running"
fi
Make the checkRunningProcess.sh executable.And then use it.
Example to use.
20:10 $ checkRunningProcess.sh proxy.py
Running
20:12 $ checkRunningProcess.sh abcdef
Not Running
I tried your version on BASH version 3.2.29, worked fine. However, you could do something like the above suggested, an example here:
#!/bin/sh
SERVICE="$1"
RESULT=`ps -ef | grep $1 | grep -v 'grep' | grep -v $0`
result=$(echo $ps_out | grep "$1")
if [[ "$result" != "" ]];then
echo "Running"
else
echo "Not Running"
fi
I use this one to check every 10 seconds process is running and start if not and allows multiple arguments:
#!/bin/sh
PROCESS="$1"
PROCANDARGS=$*
while :
do
RESULT=`pgrep ${PROCESS}`
if [ "${RESULT:-null}" = null ]; then
echo "${PROCESS} not running, starting "$PROCANDARGS
$PROCANDARGS &
else
echo "running"
fi
sleep 10
done
Check if your scripts name doesn't contain $SERVICE. If it does, it will be shown in ps results, causing script to always think that service is running. You can grep it against current filename like this:
#!/bin/sh
SERVICE=$1
if ps ax | grep -v grep | grep -v $0 | grep $SERVICE > /dev/null
then
echo "$SERVICE service running, everything is fine"
else
echo "$SERVICE is not running"
fi
Working one.
!/bin/bash
CHECK=$0
SERVICE=$1
DATE=`date`
OUTPUT=$(ps aux | grep -v grep | grep -v $CHECK |grep $1)
echo $OUTPUT
if [ "${#OUTPUT}" -gt 0 ] ;
then echo "$DATE: $SERVICE service running, everything is fine"
else echo "$DATE: $SERVICE is not running"
fi
Despite some success with the /dev/null approach in bash. When I pushed the solution to cron it failed. Checking the size of a returned command worked perfectly though. The ampersrand allows bash to exit.
#!/bin/bash
SERVICE=/path/to/my/service
result=$(ps ax|grep -v grep|grep $SERVICE)
echo ${#result}
if ${#result}> 0
then
echo " Working!"
else
echo "Not Working.....Restarting"
/usr/bin/xvfb-run -a /opt/python27/bin/python2.7 SERVICE &
fi
#!/bin/bash
ps axho comm| grep $1 > /dev/null
result=$?
echo "exit code: ${result}"
if [ "${result}" -eq "0" ] ; then
echo "`date`: $SERVICE service running, everything is fine"
else
echo "`date`: $SERVICE is not running"
/etc/init.d/$1 restart
fi
Something like this
Those are helpful hints. I just needed to know if a service was running when I started the script, so I could leave the service in the same state when I left. I ended up using this:
HTTPDSERVICE=$(ps -A | grep httpd | head -1)
[ -z "$HTTPDSERVICE" ] && echo "No apache service running."
I found the problem. ps -ae instead ps -a works.
I guess it has to do with my rights in the shared hosting environment. There's apparently a difference between executing "ps -a" from the command line and executing it from within a bash-script.
A simple script version of one of Andor's above suggestions:
!/bin/bash
pgrep $1 && echo Running
If the above script is called test.sh then, in order to test, type:
test.sh NameOfProcessToCheck
e.g.
test.sh php
I was wondering if it would be a good idea to have progressive attempts at a process, so you pass this func a process name func_terminate_process "firefox" and it tires things more nicely first, then moves on to kill.
# -- NICE: try to use killall to stop process(s)
killall ${1} > /dev/null 2>&1 ;sleep 10
# -- if we do not see the process, just end the function
pgrep ${1} > /dev/null 2>&1 || return
# -- UGLY: Step trough every pid and use kill -9 on them individually
for PID in $(pidof ${1}) ;do
echo "Terminating Process: [${1}], PID [${PID}]"
kill -9 ${PID} ;sleep 10
# -- NASTY: If kill -9 fails, try SIGTERM on PID
if ps -p ${PID} > /dev/null ;then
echo "${PID} is still running, forcefully terminating with SIGTERM"
kill -SIGTERM ${PID} ;sleep 10
fi
done
# -- If after all that, we still see the process, report that to the screen.
pgrep ${1} > /dev/null 2>&1 && echo "Error, unable to terminate all or any of [${1}]" || echo "Terminate process [${1}] : SUCCESSFUL"
I need to do this from time to time and end up hacking the command line until it works.
For example, here I want to see if I have any SSH connections, (the 8th column returned by "ps" is the running "path-to-procname" and is filtered by "awk":
ps | awk -e '{ print $8 }' | grep ssh | sed -e 's/.*\///g'
Then I put it in a shell-script, ("eval"-ing the command line inside of backticks), like this:
#!/bin/bash
VNC_STRING=`ps | awk -e '{ print $8 }' | grep vnc | sed -e 's/.*\///g'`
if [ ! -z "$VNC_STRING" ]; then
echo "The VNC STRING is not empty, therefore your process is running."
fi
The "sed" part trims the path to the exact token and might not be necessary for your needs.
Here's my example I used to get your answer. I wrote it to automatically create 2 SSH tunnels and launch a VNC client for each.
I run it from my Cygwin shell to do admin to my backend from my windows workstation, so I can jump to UNIX/LINUX-land with one command, (this also assumes the client rsa keys have already been "ssh-copy-id"-ed and are known to the remote host).
It's idempotent in that each proc/command only fires when their $VAR eval's to an empty string.
It appends " | wc -l" to store the number of running procs that match, (i.e., number of lines found), instead of proc-name for each $VAR to suit my needs. I keep the "echo" statements so I can re-run and diagnose the state of both connections.
#!/bin/bash
SSH_COUNT=`eval ps | awk -e '{ print $8 }' | grep ssh | sed -e 's/.*\///g' | wc -l`
VNC_COUNT=`eval ps | awk -e '{ print $8 }' | grep vnc | sed -e 's/.*\///g' | wc -l`
if [ $SSH_COUNT = "2" ]; then
echo "There are already 2 SSH tunnels."
elif [ $SSH_COUNT = "1" ]; then
echo "There is only 1 SSH tunnel."
elif [ $SSH_COUNT = "0" ]; then
echo "connecting 2 SSH tunnels."
ssh -L 5901:localhost:5901 -f -l USER1 HOST1 sleep 10;
ssh -L 5904:localhost:5904 -f -l USER2 HOST2 sleep 10;
fi
if [ $VNC_COUNT = "2" ]; then
echo "There are already 2 VNC sessions."
elif [ $VNC_COUNT = "1" ]; then
echo "There is only 1 VNC session."
elif [ $VNC_COUNT = "0" ]; then
echo "launching 2 vnc sessions."
vncviewer.exe localhost:1 &
vncviewer.exe localhost:4 &
fi
This is very perl-like to me and possibly more unix utils than true shell scripting. I know there are lots of "MAGIC" numbers and cheezy hard-coded values but it works, (I think I'm also in poor taste for using so much UPPERCASE too). Flexibility can be added with some cmd-line args to make this more versatile but I wanted to share what worked for me. Please improve and share. Cheers.
A solution with service and awk that takes in a comma-delimited list of service names.
First it's probably a good bet you'll need root privileges to do what you want. If you don't need to check then you can remove that part.
#!/usr/bin/env bash
# First parameter is a comma-delimited string of service names i.e. service1,service2,service3
SERVICES=$1
ALL_SERVICES_STARTED=true
if [ $EUID -ne 0 ]; then
if [ "$(id -u)" != "0" ]; then
echo "root privileges are required" 1>&2
exit 1
fi
exit 1
fi
for service in ${SERVICES//,/ }
do
STATUS=$(service ${service} status | awk '{print $2}')
if [ "${STATUS}" != "started" ]; then
echo "${service} not started"
ALL_SERVICES_STARTED=false
fi
done
if ${ALL_SERVICES_STARTED} ; then
echo "All services started"
exit 0
else
echo "Check Failed"
exit 1
fi
The most simple check by process name :
bash -c 'checkproc ssh.exe ; while [ $? -eq 0 ] ; do echo "proc running";sleep 10; checkproc ssh.exe; done'

Resources