0

recently came across an issue when running a bash script executed in a csh shell. This was outputed: /bin/bash: bad interpreter: No such file or directory. The problem was bash was not on the environment path. After adding bash, this was fixed. I want to make sure that in the future, if this ever happened again for some reason, I can handle this. I am wonder what exit code this is? or is this just printed out on stderr? I want to catch this and fail the main script. Any ideas on how to handle this?

I have this segment:

bash sc142.sh

#####################################################################
# Check for processing errors
#####################################################################
if ($status != 0) then
    exit (-1)
endif
Jose Ortiz
  • 311
  • 1
  • 3
  • 14
  • 2
    That's not what causes that error. It happens when there's a problem with the `#!` line in a script. – Barmar Apr 30 '19 at 20:26
  • Yes, the script was using the shebang line, however, bash wasn't on the same path so that's why the error happened – Jose Ortiz Apr 30 '19 at 20:28
  • Possible duplicate of https://stackoverflow.com/questions/39527571/are-shell-scripts-sensitive-to-encoding-and-line-endings – tripleee Apr 30 '19 at 20:29
  • There are no standard error codes for different problems. The only general rule is that zero is success, non-zero is failure. Some programs have specific exit statuses for different reasons, but you can't detect this specific error. – Barmar Apr 30 '19 at 20:29
  • Do you mean something like `#!/usr/bin/env bash`? That's the only way the shebag line would be sensitive to the path. – Barmar Apr 30 '19 at 20:30
  • probably better try to always use `#!/bin/sh` to prevent portability issues – nbari Apr 30 '19 at 20:30
  • 1
    It doesn't need to be on the `PATH`; `/bin/bash` tells the system exactly which binary to run. If it doesn't exist, that would be a problem, of course; perhaps you only have it installed in `/usr/local/bin/bash`? – tripleee Apr 30 '19 at 20:30
  • You can use `set -e`, so any error will halt the script. There's no way to make it specific to just this error. – Barmar Apr 30 '19 at 20:31
  • The script uses #!/bin/bash. I'm not the system admin so I can't tell you where they had it installed. There was a mass server upgrade so things were installed differently I guess – Jose Ortiz Apr 30 '19 at 20:32
  • @tripleee How does that answer this question? He's not asking why he gets the error, the question is how to detect the error and stop the calling script when it happens. – Barmar Apr 30 '19 at 20:32
  • Yes, i'm asking how to detect the issue! – Jose Ortiz Apr 30 '19 at 20:33
  • @JoseOrtiz If the script uses that, then it shouldn't matter if it's in `$PATH`. The usual cause of the problem with that line is a Windows CRLF as the line ending. – Barmar Apr 30 '19 at 20:33
  • set -e might be the perfect solution actually – Jose Ortiz Apr 30 '19 at 20:33
  • Tho kernel probably emits a specific error code but which one depends on which kernel. Is this on Linux, MacOS, *BSD, or something else? – tripleee Apr 30 '19 at 20:34
  • Can you point out an example of how to use set -e? – Jose Ortiz Apr 30 '19 at 20:34
  • They are unix machines – Jose Ortiz Apr 30 '19 at 20:35

2 Answers2

1

The exit code will be non-zero. The exact exit code depends on the environment. You may get 127 (command not found) but you may also get another non-zero exit code in certain shells.

In your csh script you can set the -e option which will cause the script to exit immediately if any commands fail.

#!/bin/csh -e
false
echo not printed
jspcal
  • 50,847
  • 7
  • 72
  • 76
1

I tried this on Debian, the exit status for a bad interpreter error is 126. So you can do:

/path/to/scriptname arg ...
if ( $status == 126 ) then
    echo "scriptname failed"
    exit 1
endif

Note that a false positive is possible. If the last command in the script you're running exits with status 126, you won't be able to tell the difference.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thank you Barmar. Have a fantastic day! – Jose Ortiz Apr 30 '19 at 20:41
  • By the way, how did you see the error number when you ran this? – Jose Ortiz Apr 30 '19 at 20:41
  • I created a script with a bad interpreter. I tried to run it, then I did `echo $?` to print the exit status. – Barmar Apr 30 '19 at 20:43
  • `$status` is the `csh` equivalent of `$?` – Barmar Apr 30 '19 at 20:43
  • Gotcha. You know, the weird thing about this is that the CSH script has a status check after the bash execution, but did not fail the program. I'll post the snippet on the question so you can take a look – Jose Ortiz Apr 30 '19 at 20:45
  • 1
    You can also use `if ( -x /bin/bash )` or `if ( -X bash )` to test if `bash` exists and is executable. – Martin Tournoij May 01 '19 at 09:09
  • @JoseOrtiz The "bad interpreter" error only happens when you run a script as a command, so it uses the shebang line to run the interpreter. If you run `bash filename` it won't happen. – Barmar May 01 '19 at 15:15
  • @Barmar Well for some reason, it still happened. It was ran using bash filename. The bash script contained the shebang line also – Jose Ortiz May 01 '19 at 15:46
  • Maybe the bash script is running another script inside, and that's getting the error. – Barmar May 01 '19 at 15:48
  • I promise you, when you use `bash filename`, the shebang line in `filename` is ignored. The `#` at the beginning makes it a comment (this is why most scripting languages use `#` as their comment prefix). – Barmar May 01 '19 at 15:49
  • @Barmar Yeah, some anomaly took place I suppose. Again, thank you very much for your help. You are very kind. Have a fantastic day! – Jose Ortiz May 01 '19 at 19:18