0

I am trying to replace all the if statements in my bash scripts with test and &&/|| because it's way easier to read for me, but I have trouble with this script, it's testing if $1 is a file and if it's not it exits

test -f "$1" || echo "$1 is not a file" && exit 1

When $1 is a file the echo command isn't executed but exit is, why ? For information I am using bash 5.1.8

3
  • 1
    Your code is no replacement for if ... then ...; else ...; fi. Commented Jul 3, 2021 at 14:14
  • I would strongly recommend against trying to use &&/|| in place of if statements. They may be easier to read, but they're much harder to understand. Their semantics can easily lead to unexpected interactions between the various commands involved; see this question and this BashPitfalls entry. Commented Jul 3, 2021 at 17:01
  • @SirCipherz : When $1 is a plain file, test -f ... sets exit code 0, which means that the command after || is not performed. This is by design of the || statement separator. Why did you expect something different? Commented Jul 5, 2021 at 7:16

1 Answer 1

1

You misunderstand what &&/|| means - it's not a ternary expression.

  • && means "if the last command you executed succeeded" while
  • || means "if the last command you executed failed"

That "last command executed" part is important. It doesn't say "the command before the first || or && on the line", as would be the case in a similar ternary expression structured as test ? exit : echo, it says the last command executed so in your code:

test -f "$1" || echo "$1 is not a file" && exit 1

it reads as pseudo-code:

IF test fails (i.e. $1 is not a file) THEN
    IF echo ... succeeds THEN
        exit 1
    ENDIF
ELSE (i.e. test succeeded and $1 is a file)
    exit 1
ENDIF

I think what you probably meant to write is:

test -f "$1" || { ret="$?"; echo "$1 is not a file" >&2; exit "$ret"; }

which means:

IF test fails (i.e. $1 is not a file) THEN
    save it's exit status in ret
    echo ...
    exit with the failure exit status from test
ENDIF
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.