'cal -h': Erro de substring de Bash '$ {string: offset: length}'

5

Cuidado com os idos de março César

Estou recebendo um erro estranho no bash usando: ${string:offset:length} .

A quinta linha de saída para o meio de março tem a saída errada:

$ 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=   

Está mostrando:

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

Mas deve ser exibido:

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

O código é bastante simples:

#!/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

Alguém pode me apontar na direção certa?

Resultado final

Aplicando correção de cal -h recomendado abaixo funcionou bem até que o Ubuntu 18.04 LTS foi lançado e testado em 28 de abril de 2018. Agora a correção recomendada por @Steve H é usada:

Alguns estão curiosos sobre o que o código faz, então eu forneci a captura de tela acima. Outros pediram o código completo e está disponível aqui: Como posso obter esta tela inicial do terminal?

    
por WinEunuuchs2Unix 11.03.2018 / 20:47

2 respostas

8

Seu problema é que cal já está destacando o dia atual e os códigos de controle estão descartando os deslocamentos

Veja /tmp/terminal em um editor hexadecimal. Hoje (dia 11) é: 5F 08 31 5F 08 31 e não 31 31

Use cal -h para desativar o realce automático da data de hoje.

    
por Martin Thornton 11.03.2018 / 21:18
1

@Martin Thornton estaria OK se todas as implementações de cal realmente reconhecessem o -h como desligando a formatação. O Debian nem mesmo o homem sugere isso. Ele exibe o uso em seu lugar. Então isso funcionaria.

cal > /tmp/terminal1
tr -cd '-60-6' < /tmp/terminal1  > /tmp/terminal

O arquivo obtém a saída de cal com formatação e a próxima linha remove qualquer coisa que não queremos e permite que o restante do código funcione.

    
por Steve H 27.04.2018 / 01:13

Tags