Bash – Fixing `${string:offset:length}` Error with `cal -h` Command

bash

Beware the Ides of March Caesar

I'm getting a weird error in bash using: ${string:offset:length}.

The fifth output line for the middle of March has the wrong output:

$ substring_test.sh
     March 2018       
Su Mo Tu We Th Fr Sa  
             1  2  3  T=   T=   T=   T=   T= 1 T= 2 T= 3 
 4  5  6  7  8  9 10  T= 4 T= 5 T= 6 T= 7 T= 8 T= 9 T=10 
11 12 13 14 15 16 17  T= T= T= 1 T= 1 T= 1 T= 1 T= 1 
18 19 20 21 22 23 24  T=18 T=19 T=20 T=21 T=22 T=23 T=24 
25 26 27 28 29 30 31  T=25 T=26 T=27 T=28 T=29 T=30 T=31 
                      T=   T=   T=   T=   T=   T=   T=   

It is showing:

T= T= T= 1 T= 1 T= 1 T= 1 T= 1

But it should show:

T=11 T=12 T=13 T=14 T=15 T=16 T=17

The code is pretty straight forward:

#!/bin/bash

cal > /tmp/terminal

CalLineCnt=1
Today=$(date +"%d")

# Prefix with space when length < 2
if [[ ${#Today} < 2 ]] ; then
    Today=" "$Today
fi

while IFS= read -r Cal; do
    printf "$Cal"
    if [[ $CalLineCnt > 2 ]] ; then
        # See if today is on current line & invert background
        for (( j=0 ; j <= 18 ; j += 3 )) ; do
            Test=${Cal:$j:2}    # Current day on calendar line
printf "T=$Test "
            if [[ "$Test" == "$Today" ]] ; then
                printf "Offset: $j "
            fi
        done
    fi
    tput cud1           # Down one line
    CalLineCnt=$((++CalLineCnt))
done < /tmp/terminal

Can anyone point me in the right direction?


End Result

Applying fix of cal -h recommended below it worked fine until Ubuntu 18.04 LTS was released and tested on April 28, 2018. Now the fix recommended by @Steve H is used:

now.png

Some are curious about the what the code does so I provided the screen shot above. Others have asked for the full code and it is available here:How can I get this terminal splash screen?

Best Answer

Your problem is that cal is already highlighting the current day, and the control codes are throwing off the offsets

Look at /tmp/terminal in a hex editor. Today (the 11th) is: 5F 08 31 5F 08 31, and not 31 31

Use cal -h to switch off the auto highlighting of today's date.

Related Question