Mais quel est ce comportement ?

There is one restriction on integer variables. Once a variable is set to integer type, it can't be assigned a non-integer value:

$ typeset —i NUM=abc 
/bin/ksh: NUM: bad number

Je ne sais pas bien si c'était à la base une idée de typer a posteriori des variables non-typées a priori, mais dans tous les cas ça pue déjà parce que pas standard comme comportement, et ensuite c'est loin d'être la meilleure idée du siècle dans l'absolu (si le langage est pourri, autant y aller jusqu'au bout !). Mais le pire du pire, c'est que l'erreur renvoyée est aussi parlante que :

script[167]: 08: bad number `08'

Hors, 167, ici, c'est un numéro de ligne qui correspond à la fin du "if" dans lequel on se trouve (if qui fait bien 40 lignes...). Tout à l'heure, j'ai vu la même erreur avec "09", ça arrive une fois toutes les deux heures en test (pour une exécution toutes les 30 secondes), sachant que ça pourrait effectivement bien être dû à une arithmétique de dates. Quelques recherches sur internet montrent que bien du monde s'est arraché les cheveux dessus. Heureusement, la solution était au milieu de tout ça...

Comme d'habitude, on retiendra qu'il faut fuir ksh. Mais décidément, les systèmes UNIX [pré-]historiques en raffolent toujours.

Edit: raté ! C'était :

        case ET_BADLIT:
                warningf(true, "%s: bad number `%s'", es->expression, str);
                break;

dans ksh/expr.c (on remarque les backquotes dans l'erreur). Mais ça ne m'avance guère plus, à vrai dire... (il semble que ce soit bien dans une assignation de variable, en tout cas)

Ré-édit:

Osanna pour Patrick ! (qui a déjà dû subir la même erreur en son temps)  Ah bien c'est que "0" suivi d'un chiffre, c'est considéré comme de l'octal, et justement :

struct tbl *
setint_v(struct tbl *vq, struct tbl *vp, bool arith)
{
        int base;
        long num;

        if ((base = getint(vp, &num, arith)) == -1)
                return NULL;

Sauf que j'avais pas capté (ça m'apprendra à tester avec $((04)) pour une erreur de "08" ou "09" !). Alors, la solution en bois sera de concaténer un "1" au début de la chaîne, et d'enlever 100 ensuite dans l'opération : berk !!

Oh, et ksh est quand même bien pourri dans ses messages d'erreur :

# echo $((4+08))
ksh: 4+08: bad number `08'
# echo $((08))
ksh: 08: bad number `08'
# HOUR=12
# MIN=03
# SEC=08
# TIME=$((HOUR*3600+MIN*60+SEC))
ksh: 08: bad number `08'
# SEC=03
# TIME=$((HOUR*3600+MIN*60+SEC))
# echo $TIME
43383