jdf
jdf

Reputation: 739

Can bash echo command return non-zero exit code?

Like the title says, is there any case where echo will exit non-zero in bash/sh?

code ex.

until monitor_thing_happens; do
  test $retry_counter -eq 0 && echo "thing didn't happen" && exit 1
  let "retry_counter--"
  echo "tries remaining: ${retry_counter}"
  sleep 5
done

In the above example, if echo exits non-zero, the && logic breaks, we never exit 1, and we loop forever. Any danger / edge case where echo can exit non-zero?

Upvotes: 12

Views: 10810

Answers (4)

Keith Thompson
Keith Thompson

Reputation: 263387

Yes, echo has a non-zero return status if there's a write error.

Quoting the bash manual:

'echo'

echo [-neE] [ARG ...]

Output the ARGs, separated by spaces, terminated with a newline. The return status is 0 unless a write error occurs.

A demonstration:

$ cat foo.bash
#!/bin/bash

echo hello
echo "The echo command returned a status of $?" > /dev/tty
$ ./foo.bash > /dev/full
./foo.bash: line 3: echo: write error: No space left on device
The echo command returned a status of 1
$ 

/dev/full is a device, similar to /dev/zero except that any attempt to write to it will fail with an ENOSPC error.

Upvotes: 12

Walter A
Walter A

Reputation: 20022

Different comments show risks. You can try

retry_counter=5
while [ retry_counter -gt 0 ]; do
   monitor_thing_happens && break
   (( retry_counter-- ))
   echo "tries remaining: ${retry_counter}"
   sleep 5
done

Not without risk ! When the function monitor_things_happen resets the same variable retry_counter the loop wil run a long time.

Upvotes: 1

totoro
totoro

Reputation: 2456

From help man (bash):

Exit Status:

Returns success unless a write error occurs.

UPDATED

So if you echo to a stream that suddenly fails, you will get another exit code.

Upvotes: 4

Mr. Llama
Mr. Llama

Reputation: 20899

Nope, no risk. From man bash:

echo [-neE] [arg ...]
Output the args, separated by spaces, followed by a newline. The return status is always 0. If -n is specified, the trailing newline is suppressed. If the -e option is given, interpretation of the following backslash-escaped characters is enabled. The -E option disables the interpretation of these escape characters, even on systems where they are interpreted by default. The xpg_echo shell option may be used to dynamically determine whether or not echo expands these escape characters by default. echo does not interpret -- to mean the end of options. echo interprets the following escape sequences:

Emphasis on "The return status is always 0".

From a code quality standpoint, I would recommend not using test unless you're forced to for shell compatibility reasons. In general, use [[, but for arithmetic expressions you can also use ((:

# The generic way
[[ $retry_counter -eq 0 ]] && echo "Thing didn't happen" && exit 1

# The arithmetic way
(( retry_counter == 0 )) && echo "Thing didn't happen" && exit 1

Upvotes: 9

Related Questions