I have a control file file.txt that always changes in value anytime depends on the other proccess.
The value of the file is like 1, 2, or 3.
I want to execute my new job when the value of control file is 3. So i need to check first the control file before do the execution job.
I was try while loop below using sleep for a moment and retry the proccess automatically every 5 seconds for 3 times, but the retry proccess is not running. How i resolved this?
#!/bin/bash
myname="kyy"
while read file; do
if [ $file == 2 ]; then
echo "`date +%Y%m%d:%H:%M:%S:%N` [ERROR]:-Value of Control File : $file "
echo "`date +%Y%m%d:%H:%M:%S:%N` [NOTICE]:-Nothing to do.. Script will exiting.."
else
echo "`date +%Y%m%d:%H:%M:%S:%N` [SUCCESS]:-Go to next step "
echo "`date +%Y%m%d:%H:%M:%S:%N` [SUCCESS]:-My name is $myname "
fi
sleep 3
((c++)) && ((c==3)) && break
done < /home/hcuseros/file.txt
This would be a simple way, where you only need to fill in your commands depending on the outcome of the test:
for i in {1..3}; do
file=$(cat test.txt)
if [ $file -eq "3" ]; then
...
else
...
fi
sleep 5
done
Related
For example, in the below script startover starts back from the top:
##########################################################################
## CHECK TIME
##########################################################################
time=$(date +%k%M)
if [[ "$time" -ge 1800 ]] && [[ "$time" -le 2200 ]];then
echo "Not a good time to transcode video!" && exit 0
else
echo "Excellent time to transcode video!" && echo "Lets get started!"
fi
##########################################################################
## CHECK TIME
##########################################################################
startover
Also keeping in mind exit 0 should be able to stop the script.
You could "recurse" using the following line:
exec bash "$0" "$#"
Since $0 is the path to the current script, this line starts the script without creating a new process, meaning you don't need to worry about too many restarts overflowing the process table on your machine.
Put it in a while loop. I'd also suggest you add a "sleep" so that you're not racing your machine's CPU as fast as it will go:
while true; do
##########################################################################
## CHECK TIME
##########################################################################
time=$(date +%k%M)
if [[ "$time" -ge 1800 ]] && [[ "$time" -le 2200 ]]; then
echo "Not a good time to transcode video!" && exit 0
else
echo "Excellent time to transcode video!" && echo "Lets get started!"
fi
##########################################################################
## CHECK TIME
##########################################################################
for i in {1..5}; do
echo $i
sleep 1
done
done
DO NOT USE WHILE LOOP at the start of the script since the condition below will exit the script and break the loop.
echo "Not a good time to transcode video!" && exit 0
You can try trapping the exit signal so that when the script exits it restarts
##########################################################################
## CHECK TIME
############bash##############################################################
trap '<path to script> ' EXIT
time=$(date +%k%M)
if [[ "$time" -ge 1800 ]] && [[ "$time" -le 2200 ]];then
echo "Not a good time to transcode video!" && exit 0
sleep 1;
else
echo "Excellent time to transcode video!" && echo "Lets get started!"
sleep 1;
fi
##########################################################################
## CHECK TIME
##########################################################################
echo 1
echo 2
echo 3
echo 4
echo 5
startover
Note: I add a sleep of 1 second because this will give you the time to see message. trap the exit signal and re-running the script is acting like a while loop. I am also assuming that these codes are in a script.
How about enclosing the entire script in a while loop? For example,
while :
do
script
done
You may want to add a condition to break out of the loop.
This is not good practice, but what you asked for.
Put this at the end of your script. "$( cd "$( dirname "$0" )" && pwd )/$(basename $0)"
I am creating a script that should wait until a certain file (e.g. stop.dat) appears or after certain time (e.g. 500 Seconds) has passed.
I know how to wait until the file appears:
while [ ! -f ./stop.dat ]; do
sleep 30
done
How can I add the other statement in my while loop?
If you want to do it this way, then you can do something like:
nap=30; slept=0
while [ ! -f ./stop.dat ] && ((slept<500)); do
sleep $nap;
slept=$((slept+nap))
done
Using inotifywait instead of polling would be a more proper way of doing it.
you could memorize the time and compare with current time in the loop condition
echo -n "before: "
date
t1=$(( $(date +"%s" ) + 15 )) #15 for testing or … your 500s later
while [ $(date +"%s") -lt $t1 ] #add other condition with -a inside the [ ] which is shortcut for `test` command, in case you want to use `man`
do
sleep 3 #do stuff
done
echo -n "after: "
date
I've got my script going as far as It can connect, login and run the command. But I'm stuck as how do I save the response from the command to a file, without saving the whole session.
#!/bin/sh
Var=1
while [ $Var -lt 20 ]
do
HOST='IPa.ddr.ess.'$Var
USER='MyUser'
PASSWD='MyPassword'
CMD='MyCommand'
(
echo open "$HOST"
sleep 1
echo "$USER"
sleep 1
echo "$PASSWD"
sleep 1
echo "$CMD"
#I want to save the output from my $cmd to an varaible $Output
#Then I want to write "$HOST - $Output" to a file named "output.txt"
sleep 2
echo "exit"
) | telnet
Var=$((Var + 1))
done
I'd appreciate any help, or pointers in the right direction
Ok, this looks more challenging than I initially thought. I like it :-)
#!/bin/sh
Var=1
while [ $Var -lt 20 ]
do
HOST='IPa.ddr.ess.'$Var
USER='MyUser'
PASSWD='MyPassword'
CMD='MyCommand'
MARKER='XXXX1234:AUIE'
(echo "$HOST - " ; (
echo unset echo
echo open "$HOST"
sleep 1
echo "$USER"
sleep 1
echo "$PASSWD"
sleep 1
echo echo "$MARKER"
echo "$CMD"
#I want to save the output from my $cmd to an varaible $Output
#Then I want to write "$HOST - $Output" to a file named "output.txt"
sleep 2
echo "exit"
) | telnet | sed -e "1,/$MARKER/d" ) >> output.txt
Var=$((Var + 1))
done
What this does is:
it disables echo-ing in telnet
After the login session, it prints a marker
anything after the marker is saved into output.txt
I imbricated into yet another shell that will print the "$HOST -" part
I am new to Bash scripting and despite multiple attempts to refactor the logic structure shown in pseudocode below I cant get this to work. How do I piece the if/else logic together with a for loop?
Pseudocode:
I have a command that checks if any subfolders exist in a directory of the HDFS filesystem. Lets call this command_A.
If subfolders do NOT exist {
proceed with remaining execution of script
}
Else {
sleep for 30 minutes and run command_A again to see if the subfolders have been removed. Note: This sleep and re-check cycle should repeat up to 4 times and if subfolders are never removed the script is killed with exit 1
}
Sample of What I Have Tried is Below. I can't figure out how I am supposed to use the || in conjunction with the else statement.
Using these structures:
1. for i in {1..4}; do command_A && break || sleep 1800; done
2. if command_A ; then echo "Command succeeded" else echo "Command failed" fi
Test Example:
for i in {1..4};
do
if hdfs dfs -test -e $mypath/*
echo "Folder is empty" && break
else
???
Update showing working solution:
for i in {1..4};
do
if hdfs dfs -test -e $mypath/*;
then
if [ $i -eq 4 ]
then
echo "script exiting now with code 1"
else
echo "Folder is full"
sleep 10
fi
else
echo "Folder is empty"
break
fi
done
UPDATE
This is the working complete code for this particular question, I'll keep the original slightly more generic code below for future reference since it is less complex (less nested if/else) for others searching for similar problems.
for i in {1..4};
do
if hdfs dfs -test -e $mypath/*;
then
if [ $i -eq 4 ]
then
echo "script exiting now with code 1"
else
echo "Folder is full"
sleep 10
fi
else
echo "Folder is empty"
break
fi
done
I think something like this will work, which is pretty much what you have. You just have to put what you're checking for in the if statement and this code should work for you.
for i in {1..4}
do
if [ <check for subdirs> ]
then
echo "Folder is empty!"
break
else
sleep 1800
fi
done
Will this work?
sleep_count=0
max_attempts=4
for ((i=0; i < $max_attempts; i++)); do
if hdfs dfs -test -e $mypath/*; then
echo "No subfolders!"
break
else
# subfolders exist; wait for a while and see if they go away
((sleep_count++))
sleep 1800
fi
done
if [[ $sleep_count == $max_attempts ]]; then
# waited too long for subfolders to go away
exit 1
fi
# probably repeat the above steps again?
I am using a code basically runs to restart a calculation after one finishes. The code was working fine. But i wanna improvise the code. Right now it runs on a timer function sleep. It never checks for the end of the file. So it waits 22 min to submit the next job irrespective of the previous job. So i want to change the code in such a way it checks the end of the file every one minute for the keyword "End of program" from the log file and submits the next job. Please drop me a msg if you have any ideas ...
while ( 1 )
#sleep for X seconds/minutes
$SLEEP 22m
#cut JobID into peeces:
#e.g.: 31380.chic1i20.informatik.tu-chemnitz.de Info: Your job definition is checked against CHiC policies. --> 31380.chic1i20
#set JOBnr = `echo $JOBID | $CUT -c-15`
set JOBnr = `echo $JOBID | $CUT -d " " -f1 | $CUT -d "." -f-2`
$QSTAT -nu "$USER" > .qstat_outfile
if ( "$?" ) then
echo "autorestart: qstat error"
$CAT .qstat_outfile
continue
endif
Try this:
UNWRITTEN=0
while [ $UNWRITTEN -eq 0 ]; do
token=$(tail -n 2 .qstat_outfile)
echo $token
if [[ $token == "End of program" ]]
then
echo "autorestart..."
UNWRITTEN=1
fi
sleep 60
done
Explanation:
Program continually loops until it find the correct line at the end of the logfile. Then it restarts your calculations and exits.
tail -n 2 reads the last two lines (which is actually the last line if there is a newline after "End of program". You may need to adjust this to -n 1 on your system.)
If I got you right, a while-loop like this may help you:
stop=0
while [ $stop == 0 ]; do
tail -1 $LOGFILE | grep -q "End of program" && stop=1 || sleep 60
done
(It checks the last line (tail -1) of LOGFILE for the presence of your search text, stops
if text is found or sleeps for 60 seconds if not).