Why does my shell script register a successful exit when it fails?

165 Views Asked by At

I have a shell script that executes whisper on all files in a directory on a network device, and then stores the resulting transcript on the same volume. Sometimes something happens with the network (the volume is disconnected) that makes the saving of the resulting transcript to fail. This is a typical such error message:

Traceback (most recent call last):
  File "/Users/db/Library/Python/3.11/bin/whisper", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/Users/db/Library/Python/3.11/lib/python/site-packages/whisper/transcribe.py", line 413, in cli
    os.makedirs(output_dir, exist_ok=True)
  File "<frozen os>", line 225, in makedirs
FileNotFoundError: [Errno 2] No such file or directory: '.'

The relevant parts of my script looks like this:

    whisper "$file" --model large >> log
    if [[ $? -eq 0 ]]; then
        echo "exit success: $?"
        echo "*****success****** $?, `uname -n`, $me"  >> "${directory}/../${transdir}/${name}.txt"
    else
        echo "exit error: $?"
        echo "*****error****** $?, `uname -n`, $me"  >> "${directory}/../${transdir}/${name}.txt"       
    fi

Normally, when the script finish successfully it enter the first if as expected, but even when I get an error message like the one above it still enters the first if as if it was successful. Why is that?

Note: AFAIK the writing to the log is not the problem.


Update:

% whisper --bad_args; echo $?
whisper: error: the following arguments are required: audio
2

Update 2:

#!/opt/local/Library/Frameworks/Python.framework/Versions/3.11/bin/python3.11
# -*- coding: utf-8 -*-
import re
import sys
from whisper.transcribe import cli
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(cli())
1

There are 1 best solutions below

0
Charles Duffy On

$? is very volatile: the moment you echo $?, the value of $? is replaced with the exit status of echo and no longer refers to the exit status of whisper. Thus, you should store it in a variable before you use it if you might ever need it more than once.

if whisper "$file" --model large >> log; then
    echo "*****success****** $?, `uname -n`, $me"  >> "${directory}/../${transdir}/${name}.txt"
else
    whisper_rc=$?                    # <- THIS RIGHT HERE
    echo "exit error: $whisper_rc"
    echo "*****error****** $whisper_rc, `uname -n`, $me"  >> "${directory}/../${transdir}/${name}.txt"       
fi