Search code examples
bashloopseofinfinite

Infinite loop in Bash showing a counter and more information


I have a script which dynamically generates another Bash script. In this heredoc script there is an infinite loop showing a counter (this works!):

date1=`date +%s`
while true; do
    echo -ne "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r";
done

This loop is working fine if you add only this. The problem is I need to show not only the counter. More information is needed (some static data). I'll add my not working code:

#!/bin/bash
dir="/tmp/"
my_file="generatedscript.sh"

rm -rf "$dir$my_file" > /dev/null 2>&1

exec 3>"$dir$my_file"

cat >&3 <<-'EOF'
    #!/bin/bash
    date1=`date +%s`
    while true; do
        echo -ne "Info\n" # this is the damned line, if you remove it the counter works fine
        echo -ne "Time counter: $(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r";
    done
EOF

exec 3>&-

xterm -hold -geometry 78x25+0+0 -T "Testing" -e "bash \"$dir$my_file\"" > /dev/null 2>&1 &

This shows the xterm window with a lot of lines and the Info line is overlapped with the "Time" word of other line. I want to show the Info line separately from the "Time counter" line and the counter running... and only once!

If you remove the line echo -ne "Info\n", the counter is showing OK, running and only once... How I can add another different line (echo with the information ) above this and as a fixed line without repetition? Is it possible?


Solution

  • Just move the INFO line out of the loop. I usually prefer to put the carriage return at the start of the line. Neither -n or -e is portable, so I usually prefer printf for all but the simplest uses of echo.

    dir="/tmp/"
    my_file="generatedscript.sh"
    
    script="$tmp/$my_file"
    cat > "$script" <<'EOF'
    echo INFO
    date1=$(date +%s)
    while true; do
      now=$(date +%s)
      delta=$((now - date1))
      printf '\rTime counter: %s' "$(date -u --date "$delta" +%H:%M:%S)"
    done
    EOF
    chmod +x 500 "$tmp/$my_file"
    xterm -hold -geometry 78x25+0+0 -T "Testing" -e "$script" > /dev/null