How to run a script in the background then when a condition is met, return it to foreground BASH - bash

I want to run a script in the background, and when the time comes bring it back from background and call another script that will take in user input from the command-line, when I use this code, it's able to run the script effectively, but when it calls the other script, it only prints out a couple lines and It isn't able to take in user input, just straight up exits out. Been at it for a couple hours, no idea what to do from here.
I call this script with ./runTool.sh &
currTime=$(ls -lu | grep test01 | awk '{print $8}')
currHour="${currTime:0:2}"
currMin="${currTime:3:3}"
check=0
while [ true ]
do
timestamp=$(ls -lu | grep test01 | awk '{print $8}')
timeHour="${timestamp:0:2}"
timeMin="${timestamp:3:3}"
if (( $timeHour > $currHour )) || (( $timeMin > $currMin )) || (($timeHour < $currHour ))
then
check=1
set -m
fg %1
./tool.sh
break
fi
sleep 1
done

Related

Bash Script can run php script manually but cannot work in Cron

I have a bash script like this:
#!/bin/bash
log_file=/home/michael/bash/test.log
checkalive=checkalive.php
#declare
needRestart=0
#Check checkalive.php
is_checkalive=`ps aux | grep -v grep| grep -v "$0" | grep $checkalive| wc -l | awk '{print $1}'`
if [ $is_checkalive != "0" ] ;
then
checkaliveId=$(ps -ef | grep $checkalive | grep -v 'grep' | awk '{ printf $2 }')
echo "Service $checkalive is running. $checkaliveId"
else
echo "$checkalive OFF"
needRestart=1
fi
#NEED needRestart
if [ $needRestart == "1" ];
then
#START SERVICE
echo "Restarting services..."
/usr/bin/php5.6 /home/michael/bash/$checkalive >/dev/null 2>&1 &
echo "$checkalive..."
echo `date '+%Y-%m-%d %H:%M:%S'` " Start /home/michael/bash/$checkalive" >> $log_file
fi
I can run it manually but when I try to run it in Cron, it doesn't work for some reasons. Apparently the command:
/usr/bin/php5.6 /home/michael/bash/$checkalive >/dev/null 2>&1 &
does not work.
All of file permissions are already set to executable. Any advice?
Thank you
You have run into one of cron's most common mistakes, trying to use it like an arbitrary shell script. Cron is not a shell script and you can't do everything you can do in one, like dereferencing variables or setting arbitrary new variables.
I suggest you replace your values into the cron line and avoid usage of variables
/usr/bin/php5.6 /home/michael/bash/checkalive.php >/dev/null 2>&1 &
Also, consider removing the trailing & as it is not necessary.

Bash idle session times greater than 15 min

I need help completing this. Trying to take user sessions sitting idle for greater than 15 minutes which aren't being kicked off by sshd_config and kill them. this is what I have to pull the sessions, how do I filter for greater than 15 minutes.
#!/bin/bash
IFS=$'\n'
for output in $(w | tr -s " " | cut -d" " -f1,5 | tail -n+3 | awk '{print $2}')
do
echo "$output \> 15:00"
done
If you are using Awk anyway, a shell loop is a clumsy antipattern. Awk already knows how to loop over lines; use it.
A serious complication is that the output from w is system-dependent and typically reformatted for human legibility.
tripleee$ w | head -n 4
8:16 up 37 days, 19:02, 17 users, load averages: 3.49 3.21 3.11
USER TTY FROM LOGIN# IDLE WHAT
tripleee console - 27Aug18 38days -
tripleee s003 - 27Aug18 38 ssh -t there screen -D -r
If yours looks similar, probably filter out anything where the IDLE field contains non-numeric information
w -h | awk '$5 ~ /[^0-9]/ || $5 > 15'
This prints the entire w output line. You might want to extract just the TTY field ({print $2} on my system) and figure out from there which session to kill.
A more fruitful approach on Linux-like systems is probably to examine the /proc filesystem.
You can try something like this …
for i in $(w --no-header | awk '{print $4}')
do
echo $i | grep days > /dev/null 2>&1
if [ $? == 0 ]
then
echo "greater that 15 mins"
fi
echo $i | grep min> /dev/null 2>&1
if [ $? == 0 ]
then
mins=$(echo $i | sed -e's/mins//g')
if [ $min -gt 15 ]
then
echo "Greater than 15 mins"
fi
fi
done
The tricky part is going to be figuring out what pid to kill.

Continuous If statement

I have 2 scripts one is software.sh and the other timer.sh both get executed in separate terminals. I want the if statement that checks for software execution duration to be checking continuously but apparently it only gets checked once at start of execution :(
This is the timer.sh which gets the PID of software.sh and counts its running time
#!/bin/bash
while ((1)); do
PID_Ardu=$(pidof arducopter)
Time= ps -p $PID_Ardu -oetime= | tr '-' ':' | awk -F: '{ total=0; m=1; } { for (i=0; i < NF; i++) {total += $(NF-i)*m; m *= i >= 2 ? 24 : 60 }} {print total}'
if [[ $Time < 20 ]]; then **#THIS SHOULD BE EXECUTED CONTINOUSLY**
echo $Time
else
echo INSIDE
ps -ef | grep software| grep -v grep | awk '{print $2}' | xargs kill
fi
done
This is software.sh which executes various generated files
#!/bin/bash
chmod a+x *.exp
./ACCF01.exp | wait |echo "FINISHED SCRIPT 1" #Run the ACCF01 script
sed -i '/ACCF01.exp/d' ./software.sh #Delete previous line after finishing execution.
./ACCF02.exp | wait |echo "FINISHED SCRIPT 2"
sed -i '/ACCF02.exp/d' ./software.sh
./ACCF03.exp | wait |echo "FINISHED SCRIPT 3"
sed -i '/ACCF03.exp/d' ./software.sh
./ACCF04.exp | wait |echo "FINISHED SCRIPT 4"
The Time variable is assigned a string, not the return value of the pipeline, because it needs to enclose it in $(..) or backticks.
In any case the If is executed multiple times, it just has no changing numerical value in the variable.
When you try to debug loops and variable assignments you can use set -x or start with bash -x time.sh in the future. It will print out all lines execute and variables expanded.

I am trying to tail a log file and check for server up condition, once the string matches, it should return the same O/P in the variable.

The problem is that tail -f doesn't exits by itself and my script stalls.
I am using sleep 15 because after triggering the shutdown command string 'org.apache.coyote.AbstractProtocol' appears after 15 sec in logs. In this way tail -100 works and gives the desired result.
Below is the snippet of code which I have written and its working fine, but I want to check it dynamically by tail -f. Please guide me how can I do it by tail -f and exiting the tail by some way.
ALFRESCO_LOGS="$CATALINA_BASE/logs"
printf "Stopping alfresco instance.\n\n"
$CATALINA_HOME/bin/shutdown.sh &> /dev/null
sleep 15
CHECK_ALFRESCO_LOGS=$(tail -100 $ALFRESCO_LOGS/catalina.out | grep --line-buffered 'org.apache.coyote.AbstractProtocol' | awk 'NR==1{print $NF}')
echo "$CHECK_ALFRESCO_LOGS"
if [[ "$CHECK_ALFRESCO_LOGS" == "stop" ]];
then
echo "Alfresco instance has been stopped."
fi
If you're OK with tail -f receiving SIGPIPE, this is a straightforward way:
while read CHECK_ALFRESCO_LOGS; do
echo "$CHECK_ALFRESCO_LOGS"
if [[ "$CHECK_ALFRESCO_LOGS" == "stop" ]]; then
echo "Alfresco instance has been stopped."
break
fi
done < <( tail -f $ALFRESCO_LOGS/catalina.out | awk '/org.apache.coyote.AbstractProtocol/{print $NF}')
When the condition matches, the while loop ends. That closes the input redirection, and thus the tail process receives SIGPIPE, which closes it.

Error Handling on bash script

Infinite loop on bash script and I want to run forever but (I guess) something goes wrong script is killed. Is there any way like try-catch, just continue to running forever, unconditionaly.
#!/bin/bash
iteration=0
for (( ; ; ))
do
process_id=`ps -ef | grep java | grep TEST | awk '{print $2}' `
kill_command='kill -3 '$process_id
time=`date | awk '{print substr($4,0,5)}' `
last_write=`ls -l /files/*.txt | awk '{print $8}' `
if [ "$time" != "$last_write" ]
then
$kill_command
sleep 1
$kill_command
sleep 1
$kill_command
sleep 1
/test/show_queue.sh
fi
let "iteration+=1"
if [ "$iteration" == "30" ]
then
let "iteration=0"
$kill_command
echo '------------' >> memory_status.log
date >> memory_status.log
prstat -n 7 1 1 >> memory_status.log
echo '------------' >> memory_status.log
/test/show_queue.sh
fi
sleep 60
done
A very simple way to do it is to use two scripts. One with the loop and one which does the killing task :
for (( ; ; ))
do
DoKillingTask
rc=$? # <- You get the return code of the script and decide what to do
done
If it continues to be killed, Mikel (in comment of your question) is right.

Resources