De Manual de referência do Bash :
${parameter:?word}
If
parameter
is null or unset, the expansion ofword
(or a message to that effect ifword
is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value ofparameter
is substituted.
Pode não ser óbvio, mas "erro padrão" aqui significa o erro padrão do shell . Quando você faz echo … 2> testfile
, você redireciona o erro padrão de echo
. Ambos normalmente acabam no seu terminal, mas não são os mesmos.
Para que funcione como você deseja criar uma subshell e redirecionar o seu erro padrão:
(echo ${var:?"This var is not set"}) 2> testfile
Isso também funcionará:
{ echo ${var:?"This var is not set"}; } 2> testfile
Observe que o comando real ( echo
) herdará o erro padrão já redirecionado do subshell, portanto, esse redirecionamento afeta os dois. Quase nunca importa quando o comando é echo
, mas com um comando que retorna uma mensagem de erro. Comparar:
unset var
(dd ${var:?"This var is not set"}) 2> testfile
cat testfile
var=foo
(dd ${var:?"This var is not set"}) 2> testfile
cat testfile