Não use expr para aritmética. Há muito tempo está obsoleto: os shells agora possuem aritmética integrada, com a construção $((…)) (POSIX) ou com let builtin (ksh / bash / zsh) ou a construção ((…)) (ksh / bash / zsh).
let e ((…)) return 1 (um código de status de falha) se a última expressão avaliada for 0. Para evitar que esse script saia em set -e , organize a última expressão para não retornar 0, para exemplo:
let "a = 2 - 2" 1
((a = 2 - 2, 1))
Como alternativa, use o || true idiom:
((a = 2 - 2)) || true
Como alternativa, faça sua aritmética dentro de $((…)) e suas atribuições fora. Uma atribuição retorna o status da última substituição de comando no valor, ou 0, se não houver substituição de comando, portanto, você está seguro. Isso tem o benefício adicional de trabalhar em qualquer shell POSIX (como dash).
a=$((2 - 2))