I know I can wait on a condition to become true in bash by doing:
while true; do
test_condition && break
sleep 1
done
But it creates 1 sub-process at each iteration (sleep). I could avoid them by doing:
while true; do
test_condition && break
done
But it uses lot of CPU (busy waiting). To avoid sub-processes and busy waiting, I came up with the solution bellow, but I find it ugly:
my_tmp_dir=$(mktemp -d --tmpdir=/tmp) # Create a unique tmp dir for the fifo.
mkfifo $my_tmp_dir/fifo # Create an empty fifo for sleep by read.
exec 3<> $my_tmp_dir/fifo # Open the fifo for reading and writing.
while true; do
test_condition && break
read -t 1 -u 3 var # Same as sleep 1, but without sub-process.
done
exec 3<&- # Closing the fifo.
rm $my_tmp_dir/fifo; rmdir $my_tmp_dir # Cleanup, could be done in a trap.
Note: in the general case, I cannot simply use read -t 1 var
without the fifo, because it will consume stdin, and will not work if stdin is not a terminal or a pipe.
Can I avoid sub-processes and busy waiting in a more elegant way ?
true
is a builtin and does not create a sub process in bash. busy waiting will always be bad. – jordanm Mar 17 '13 at 17:47true
, question updated. – jfg956 Mar 17 '13 at 17:59read -t 1 var
. – ott-- Mar 17 '13 at 18:21sleep
as in the first example. The second one, while it may work, is not going to be easy for anyone to adjust in the future. Simple code also have bigger potential for being safe. – Kusalananda Jan 31 '18 at 09:33