Para responder a minha própria pergunta, bloqueando uma maneira de sinalizar variáveis não declaradas como inválidas em bc, criei uma solução viável caso seja útil para outras pessoas. A expressão a ser executada por bc é primeiramente canalizada através de um comando sed, que retira quaisquer palavras bc reservadas da expressão. Quaisquer nomes de variáveis restantes são considerados variáveis não declaradas, e toda a expressão é convertida em uma instrução que forçará um erro quando executada em bc (eu escolhi '1/0', mas qualquer um de um número de sinalizadores de erro alternativos poderia ser construído .)
Gera um erro "Dividir por zero" em tempo de execução:
echo 'foo + bar' | sed -E '
## Save the original expression in the hold space
h
## Recursively replace all bc reserved words with a unique token string (¦§§¦)
:again
s/auto|break|continue|define|else|for|halt|ibase|if|last|length|limits|obase|print|quit|read|return|scale|sqrt|warranty|while/¦§§¦/g
s/(a|c|e|j|l|s)([(][^)]*[)])/¦§§¦/g
t again
## If the expression contains any bc reserved words abutting one another, mark the expression as invalid, and skip to the end of the sed script
/¦§§¦¦§§¦/s/^.+$/1\/0/
t
## Replace all tokens with spaces
s/¦§§¦/ /g
## If any variable names remain, treat them as undeclared variables, mark the expression as invalid, and skip to the end of the sed script
## Prior to doing this, reset the t command so that it can recognize if a substitution takes place in the s command
t reset
:reset
/[a-z][a-z0-9_]*/s/^.+$/1\/0/
t
## If the expression does not have undeclared variable names, get the original expression from the hold space
g
' | bc -l
Retorna a resposta correta = 246:
echo '123 + 123' | sed -E '
## Save the original expression in the hold space
h
## Recursively replace all bc reserved words with a unique token string (¦§§¦)
:again
s/auto|break|continue|define|else|for|halt|ibase|if|last|length|limits|obase|print|quit|read|return|scale|sqrt|warranty|while/¦§§¦/g
s/(a|c|e|j|l|s)([(][^)]*[)])/¦§§¦/g
t again
## If the expression contains any bc reserved words abutting one another, mark the expression as invalid, and skip to the end of the sed script
/¦§§¦¦§§¦/s/^.+$/1\/0/
t
## Replace all tokens with spaces
s/¦§§¦/ /g
## If any variable names remain, treat them as undeclared variables, mark the expression as invalid, and skip to the end of the sed script
## Prior to doing this, reset the t command so that it can recognize if a substitution takes place in the s command
t reset
:reset
/[a-z][a-z0-9_]*/s/^.+$/1\/0/
t
## If the expression does not have undeclared variable names, get the original expression from the hold space
g
' | bc -l
Editar nota: este é um refinamento do meu envio original e é mais preciso na detecção de nomes de variáveis não declaradas.