Como são strings, você pode comparar várias strings concatenadas entre si. O balanceamento de valores é um meio simples de lidar com vários testes de shell de uma só vez.
[ "${num#90.}${num%[!0]*}" = "90${num%[!0]*}" ] && do_it
Mas isso só funciona se $num for definitivamente um número. Você pode validar um valor inteiro para $num como:
[ "$num" -eq "$num" ]
Ou um float como:
[ "${#num}${num#*.}" -ne "${num%.*}${#num}" ]
Mas case geralmente é melhor ...
case ".${num##*[!-.0-9]*}" in
(.|.[!9]*|.9[!0]*|.90.*[!0]*)
! :;;esac
No que diz respeito a utilitários externos, geralmente prefiro dc to bc porque ele pode ser usado para executar comandos arbitrários do sistema:
dc -e '[!echo execute arbitrary system command]s=' \
-e '90 90.0 =='
Tudo dentro dos colchetes [] é uma string que é s aved para a matriz chamada = e que é executada como um comando dc se os dois principais valores na pilha principal (aqui 90 e 90.0) = um do outro. O primeiro operador ! dentro da cadeia é o operador ! , que executa como um comando do sistema tudo o que o segue. Você também pode ler a entrada para mais script dc para executar condicionalmente com o operador ? .
A sintaxe -e xpression é um GNUism, no entanto. Você pode obter o mesmo efeito portável com um heredoc ou ecoar os comandos em um cano para seu stdin.
Por exemplo:
! dc -e '[!kill -PIPE "$PPID"]s= 90 90.0 ==' && do_it