O que pode ser feito é usar funções. Eles correm como subshells, então você pode pegar erros de um subshell via redirecionamento, e enviá-lo para outra função para lidar com ele. O script abaixo lida apenas com falha de um comando.
#!/bin/bash
err_handling()
{
# grab command from output
cmd=$(awk -F ':' '{print }' < /dev/stdin)
# re-run with some proper argument
$cmd /dev/sda1
}
main()
{
# let main stop on error
# so note , last line won't run !!!
set -e
# This will fail with df: asdf: No such file or directory
# err_handling function will grab the command name
# and rerun it
df asdf
echo "Last line"
}
# Run main with redirecting stderr to stdout
# and original stdout to /dev/null. That way
# only stderr goes via pipe
main 2>&1 >/dev/null | err_handling
Você poderia manipular vários comandos se dissesse awk
para filtrar a saída. Por exemplo, isto lê todo o formulário stderr main, e para cada linha err, extrai o comando. case...esac
é usado para tratar casos específicos de erros
#!/bin/bash
err_handling()
{
while read line
do
# grab command from output
cmd=$(awk -F ':' '{print }' <<< "$line" )
# re-run with some proper argument
case $line in
# do something with cmd depending on error
*not\ found*) echo "$cmd wasn't found" ;;
*No\ such\ file*) echo "$cmd didn't find your file" ;;
esac
done
}
main()
{
# let main stop on error
# so note , last line won't run if set -x is set !!!
# set -x
# This will fail with df: asdf: No such file or directory
# err_handling function will grab the command name
# and rerun it
df asdf
asdf
}
# Run main with redirecting stderr to stdout
# and original stdout to /dev/null. That way
# only stderr goes via pipe
main 2>&1 >/dev/null | err_handling
Note, como eu menciono nos comentários - alguns comandos não usam o stderr, por exemplo o comando file
. Nesse caso, você precisa redirecionar seu stdin e manipulá-lo via pipe ou de outra forma