0

I am new to bash scripting and I am trying to understand the following line:

# Verify pre-req environment
command -v kubectl > /dev/null 2>&1 || { echo "kubectl pre-req is missing."; exit 1; }

I unerstand this part: command -v kubectl > /dev/null 2>&1 so if it fails or not we redirect the output to /dev/null in which if I understand it correctly means ignore it in all cases. So in what cases the following line will be executed then?

{ echo "kubectl pre-req is missing."; exit 1; }

and how || behaves in this case?

Carlos
  • 331
  • 6
  • 14
Learner
  • 1,686
  • 4
  • 19
  • 38

4 Answers4

2

I unerstand this part: command -v kubectl > /dev/null 2>&1 so if it fails or not we redirect the output to /dev/null in which if I understand it correctly means ignore it in all cases.

You've misunderstood that; no part of command -v kubectl > /dev/null 2>&1 has any connection to "if it fails" vs. "not".

Rather, > and 2> redirect two different types of output; > (or 1>) redirects whatever the command writes to standard output, and 2> redirects whatever the command writes to standard error. Whether the command writes anything to standard output is independent of whether it ends up succeeding or failing; whether it writes anything to standard error is independent of whether it ends up succeeding or failing; and whether it writes anything to standard output is independent of whether it writes anything to standard error.

For example, here is a command that prints to both standard output and standard error, and then returns successfully:

( echo "this is on standard output" ; echo "this is on standard error" >&2 ; exit 0 )

and here is one that prints to both standard output and standard error, and then fails:

( echo "this is on standard output" ; echo "this is on standard error" >&2 ; exit 1 )

By contrast, || really does have to do with whether a command succeeds (exiting with zero) or fails (exiting with something other than zero).

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • The `curl` command (which does things like downloading web pages) is a good example of this. By default, it sends downloaded data to standard output and status updates (e.g. download progress) to standard error. So it writes to standard error whether or not there's a problem. `curl` also uses its exit code to indicate whether an error occurred and if there was an error, the general nature of it (e.g. 0 = success, 7 = failed to connect to host, etc). Suppressing the messages, either with `2>/dev/null` (or similar), or with `curl`'s `-s` or `--silent` option, has no effect on the exit code. – Gordon Davisson Sep 26 '19 at 03:45
2

|| is used for OR condition in bash.

For a simplified example lets look at

 cmd1 || cmd2

What happens is that if cmd1 succeeds (i.e. exit code 0), then cmd2 will NOT be performed. cmd2 will only be performed if cmd1 fails.

This is one reason why returning exit codes is so important.

For more details, please look at this post: Boolean operators ( &&, -a, ||, -o ) in Bash

Hansraj Das
  • 209
  • 4
  • 7
1

If the kubectl command exits with a non-zero exit status, the code after the || will be executed.

$ sh -c 'exit 42' && echo "exit status zero" || echo "exit status non-zero"
exit status non-zero

$ sh -c 'exit 0' && echo "exit status zero" || echo "exit status non-zero"
exit status zero
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 2
    Notice that this isn't *exactly* if/then/else: if the command between `&&` and `||` fails, the command after `||` will be run. – Benjamin W. Sep 25 '19 at 18:23
1

|| is a logic or and acts based on previous command exit code (0 means true and other value is false).

In this case, it will only execute the echo part when the first command (kubectl..) exit code is not 0 (i.e: fails). The exit 1 is to make the whole command fail, otherwise the exit code would be 0 from echo command.

Gonzalo Matheu
  • 8,984
  • 5
  • 35
  • 58