Bash: infinite sleep (infinite blocking)
sleep infinity
does exactly what it suggests and works without cat abuse.
Implementing infinite wait in shell scripting
you can use a named pipe for your read:
mkfifo /tmp/mypipe
#or mknode /tmp/mypipe p
if you later want to send different arbitrary "signals" to the pipe, the read can be use in combination with a case statement to take appropriate actions (even useful ones)
while read SIGNAL; do
case "$SIGNAL" in
*EXIT*)break;;
*)echo "signal $SIGNAL is unsupported" >/dev/stderr;;
esac
done < /tmp/mypipe
Linux Bash infinite loop with sleep
First, you need a sleep, like the one in GNU coreutils, that understands fractional seconds. If yours does, then:
sleep $(echo "1.2 - $diff/1000" | bc -l)
Alternatively, your loop could be simplified to:
while true
do
date1=$(date +%s%N)
php /var/www/html/sprint/yii hello/validate
wait
date2=$(date +%s%N)
sleep $(echo "1.2 - ($date2-$date1)/1000000000" | bc -l)
done
On the other hand, if we want to keep a printout of elapsed time:
while true
do
date1=$(date +%s%N)
php /var/www/html/sprint/yii hello/validate
wait
diff=$(echo "($(date +%s%N) - $date1)/1000000" | bc -l)
echo "That took $diff milliseconds."
time sleep $(echo "1.2 - ($diff)/1000" | bc -l)
done
is it better to use sleep() or an infinite loop to wait for an event?
Both alternatives are undesirable. Normally, you would use a blocking read. I assume it looks something like this (since you say you are waiting for the server):
while (!ssh_channel_poll(...)) { ... }
ssh_channel_read(...);
In this case, the poll
is unnecessary. Just make sure the SSH connection is a blocking connection, and the read
function will wait until data is available if none is available when you call it.
// This is all you need.
ssh_channel_read(...);
Exit from BASH Infinite loop in a pipeline
When head
exits, the standard output of the parenthesized expression is closed. If an external command, like date
, is used, the loop hangs. If an internal command of bash is used, like echo
, the loop exits. For proof, use
(while true; do /bin/echo xxx; done) | head -n 1
and it will hang. If you use
(while true; do date; echo $? 1>&2; sleep 1; done) | head -n 1
you will see that on the second round, the date
command returns an error exit code, i.e. something other but zero. Bash obviously does this not take as serious as when an internal command gets into problems. I wonder if this is intended or rather a bug in bash.
To make sure the loop is exited, this seems to work:
(set -e; while true; do date ; done) | head -n 1
Why would I use Sleep() with infinite timeout?
There's no reasons one in his sane mind would ever Sleep(INFINITE). It has no practical meaning.
It is for generality and symmetry to WaitForSingleObject(..., timeout) and SleepEx(timeout), where INFINITE does make sense.
Reminding, that SleepEx will try to consume things out of your thread's APC queue.
Interrupt sleep in bash with a signal trap
#!/bin/bash
trap 'echo "Caught SIGUSR1"' SIGUSR1
echo "Sleeping. Pid=$$"
while :
do
sleep 10 &
wait $!
echo "Sleep over"
done
Why can't I CTRL-C a sleep infinity in docker when it runs as PID 1
Would this be of any use? https://www.fpcomplete.com/blog/2016/10/docker-demons-pid1-orphans-zombies-signals
Basically the problem is process number 1. Linux/unix kernels are reluctant to signal that process the regular way, as it is supposed to be init. If init process dies, the system issues a panic immediately and reboots. If your process 1 does not have a handler to a signal, the signal just gets dropped. Sleep does not have handlers for any signals but you can build one to bash script.
Basically what you need to do is use exec form in your dockerfile, and split your sleep infinity into a loop as bash traps do not get triggered while shell is executing a command. This sends a signal to the running process 1 and catches it:
Dockerfile:
FROM ubuntu
ADD foo.sh /tmp
RUN ["/tmp/foo.sh"]
foo.sh:
#!/bin/bash
trap "echo signal;exit 0" SIGINT
while :
do
sleep 1
done
This will react to docker kill --signal=SIGINT.
bash: while loop going to infinite loop while case statement
Your outer function has redirected standard input to read from the cut
process substitution, so that's where read
is reading its input from.
Perhaps use a separate file descriptor for the process substitution.
Furthermore, your verify
function recursively calls check_status
again; probably take that out!
verify()
{
while true ;do
read -p "Have you fixed? Yes/No: " yn
case $yn in
YES|Yes|yes|y|Y)
echo "Hola"
# check_status # DON'T!
break
;;
NO|No|no|n|N)
echo "Please fix"
;;
*)
echo "Please answer yes or no."
;;
esac
done
}
check_status()
{
# Notice read -u 3 to read from fd3
# Notice _ to read fields 3 and up
while IFS=" " read -u 3 -r rec1 rec2 _
do
# Syntax: single =, add quoting
if [ "$rec2" = 'up' ]
then
echo "$rec1 is up"
else
echo "$rec1 is down so please fix"
verify
fi
# Notice 3<
done 3< compute_list
}
check_status
I also took the liberty to fix your indentation and avoid the unnecessary process substitution; read
can perfectly well read and discard the fields after the second.
printf
is more versatile than echo
but in this case, when you simply want to output static strings, I switched to echo
.
Demo: https://ideone.com/pVerFm
(I left in the process substitution there in case you want to see what it looks like syntactically.)
Related Topics
How to Trim White Space from a Variable in Awk
Generating a Sha-256 Hash from the Linux Command Line
Is /Usr/Local/Lib Searched for Shared Libraries
User-Data Scripts Is Not Running on My Custom Ami, But Working in Standard Amazon Linux
Receiving Key Press and Key Release Events in Linux Terminal Applications
Why Redirect Stdin Inside a While Read Loop in Bash
Command to Change the Default Home Directory of a User
How to See Full Absolute Path of a Symlink
Don't Add "+" to Linux Kernel Version
Crontab Run Every 15 Minutes Except at 3Am
Prevent Gnome Terminal from Exiting After Execution
Replacing Control Character in Sed
Need Text to Speech and Speech Recognition Tools for Linux
Bash Script to Remove 'X' Amount of Characters the End of Multiple Filenames in a Directory