5

I have a script to check my environment, and I would like to ask your advice on how to handle "command not found" errors.

echo "...RVM Version : $(rvm -v)" echo "...Node Version : $(node -v)" echo "...Ruby Version : $(ruby -v)" echo "...Bundler Version : $(bundle -v)" echo "...Passenger Version: $(passenger -v)" 

It shows "command not found" for the node and passenger commands:

...RVM Version : rvm 1.29.7 (latest) by Michal Papis deploy_confirm.sh: line 10: node: command not found ...Node Version : ...Ruby Version : ruby 2.6.0p0 (2018-12-25 revision 66547) ...Bundler Version : Bundler version 2.0.1 deploy_confirm.sh: line 13: passenger: command not found ...Passenger Version: 

Instead of showing an error I would like to show "Not found", like this:

...RVM Version : rvm 1.29.7 (latest) by Michal Papis ...Node Version : Not found ...Ruby Version : ruby 2.6.0p0 (2018-12-25 revision 66547) ...Bundler Version : Bundler version 2.0.1 ...Passenger Version: Not found 

3 Answers 3

5

Insert this before your first echo line if you use bash >= 4.0:

command_not_found_handle() { echo "not found"; return 127; } 

And then insert this after your last echo line to get rid of this function:

unset command_not_found_handle 

Output, e.g.:

 ...RVM Version : not found ...Node Version : v4.2.6 ...Ruby Version : ruby 2.3.1p112 (2016-04-26) [x86_64-linux-gnu] ...Bundler Version : not found ...Passenger Version: not found 
Sign up to request clarification or add additional context in comments.

6 Comments

You might want to make sure command_not_found_handle still returns 127.
@Cyrus, I'd be wary of this -- it'll last well after the OP has printed their info block, thus adding not-found info to stdout rather than stderr for as long as it remains defined.
Thanks for the hints to @chepner and Charles. I've updated my answer.
Interesting, I've never seen that before, thanks for the tip. The obvious problem is that command_not_found_handle() might have been defined to be something else before you redefined it. Ideally you'd save it before defining and restore it afterwards rather than just unsetting it afterwards.
@EdMorton: Thanks for the hint. Yes, that would be a functionality that could be added if necessary.
|
4

A wrapper function is an easy way to get customized behavior, especially in a scenario where changing that behavior globally would be undesirable.

or_not_found() { if type "$1" >/dev/null 2>&1; then # if given a valid command "$@" # run that command with original arguments else echo "Not found" # write to stdout so it's captured by the command substitution fi } echo "...Login Shell User : $USER" # much more efficient than calling whoami echo "...RVM Version : $(or_not_found rvm -v)" echo "...Node Version : $(or_not_found node -v)" echo "...Ruby Version : $(or_not_found ruby -v)" echo "...Bundler Version : $(or_not_found bundle -v)" echo "...Passenger Version: $(or_not_found passenger -v)" 

1 Comment

@TranNghi this will do what you asked for though, the other commands here won't as they'll mix commands not found with commands that don't support the given argument. Try the alternatives with cut -v as the command. Charles script will correctly print cut: unknown option -- v Try 'cut --help' for more information. to stderr while Johns, for example, will incorrectly print Not found.
3

Use 2>/dev/null to suppress the error message and || as short hand for else. a || b will run b if command a fails.

echo "...Login Shell User : $(whoami)" echo "...RVM Version : $(rvm -v 2>/dev/null || echo 'Not found')" echo "...Node Version : $(node -v 2>/dev/null || echo 'Not found')" echo "...Ruby Version : $(ruby -v 2>/dev/null || echo 'Not found')" echo "...Bundler Version : $(bundle -v 2>/dev/null || echo 'Not found')" echo "...Passenger Version: $(passenger -v 2>/dev/null || echo 'Not found')" 

1 Comment

That would print Not found for any command that actually IS found but doesn't support the given argument (e.g. -v) or has any other problem upon invocation (can't read a config file, can't open a library, detects some resource conflict, memory issue, processor occupancy issue, permissions issue, etc.) and would hide the real error message. The way to find out if a command is available or not is by using type command, not calling the command and assuming a failure means the command doesn't exist. See stackoverflow.com/a/55993789/1745001.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.