3

The following command works:

$ expr 1 : '\(.\)' || echo fail
1

When trying to match the string "0" the command fails, e.g. $? == 1:

$ expr 0 : '\(.\)' || echo fail
fail

The man page says:

Exit status is 0 if EXPRESSION is neither null nor 0

But, returning exit status 1 because the matching string is 0 does not make sense.

Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • 1
    `expr` shouldn't be used in bash code at all; it's an artifact of the 1970s, and not part of the shell at all (invoking it starts a separate executable, `/usr/bin/expr`). – Charles Duffy Sep 07 '20 at 17:38
  • 1
    ...if you want to use bash's built-in regex code, `[[ 1 =~ (.) ]]` is the alternative -- and its behavior is more sensible (evaluates as truthy if there's a match, even if its content is `0`). – Charles Duffy Sep 07 '20 at 17:39
  • @DagLöwenvald : I don't know what is the intended purpose of your statement, but for all digits `d`, `expr $d : '\(.\)'` write $d to stdout. Hence, the exit status is 1 if `d=0`, and 0 for other values of `d`. – user1934428 Sep 08 '20 at 06:12

2 Answers2

2

The exit status of expr depends on the string returned, not the operation that produces that string.

 The expr utility exits with one of the following values:
 0       the expression is neither an empty string nor 0.
 1       the expression is an empty string or 0.
 2       the expression is invalid.

Since the returned string is 0, the exit status is 1.

Whether you use a successful regular expression match or some other operator to produce the 0 isn't relevant.

$ expr 3 - 3 || echo "fail"
0
fail
chepner
  • 497,756
  • 71
  • 530
  • 681
0

It looks like expr just evaluates 0 as an error case:

$ expr 1
$ echo $?
0

$ expr 0
$ echo $?
1
perreal
  • 94,503
  • 21
  • 155
  • 181