5

In a shell script, I have the following code to exit early if the database is offline;

Br3trans -u / -c -f dbstate && ( echo Datenbank ist online. ; echo Nächster Schritt... ) || ( echo "Datenbank ist offline" ; exit 1 );
echo Test

If the database is offline, it doesn't exit the script and instead goes to echo "Test".

Any ideas?

2
  • 8
    Generally writing 'if .. then .. else' constructs with && and || is not a good idea as the && or || command actually only acts on the exit-status of the previous command. As an example, in the construct command && true-action || false-actionone would expect that the "false-action" is only executed when the command fails. While most of the time this seems to be the case, in reality the || command could also be unexpectedly triggered by the "true-action" failing.
    – bey0nd
    Commented Feb 18, 2020 at 8:21
  • 6
    From the title I thought this was going to be about vi ;) Commented Feb 18, 2020 at 13:01

2 Answers 2

17

The exit statement exits the subshell.

If you unroll your one-liner it will start to work as you expect

#!/bin/bash
if Br3trans -u / -c -f dbstate
then
    echo "Datenbank ist online."
    echo "Nächster Schritt..."
else
    echo "Datenbank ist offline"
    exit 1
fi
echo Test

Alternatively, in some shells you can use a grouping {...} instead of a subshell (...), but I think for readability it would be better to use the slightly longer version I've given you.

3
  • Thank's for your help. But now i have a other issue. "line 11: syntax error: unexpected end of file", but i dont had a 11 line.
    – plattio
    Commented Feb 18, 2020 at 8:21
  • 6
    You've probably missed either a double-quote (") or part of the if...then...else...fi structure. Try copying your code into shellcheck.net and see what it tells you. Commented Feb 18, 2020 at 8:34
  • 6
    If shell complains about a line beyond the end of your script, it means it ran off the end of your file while expecting some syntax element. Typically: unbalanced quotes, or brackets, of any type: ' " ` { } ( ) [ ] [[ ]]. Or do-done, if/then/else/fi, and so on. Commented Feb 18, 2020 at 13:35
9

I think your problem is that you have the exit command in a ( ... )-enclosed group, which will execute all commands inside in a sub-shell specifically created for that command group only. So, your exit statement only applies to the sub-shell and not the main shell used to run your script.

In this case, I would recommend explicit test commands instead of the "one-liner" approach:

#!/bin/bash

if Br3trans -u / -c -f dbstate
then
   echo "Datenbank ist online"
   echo "Nächster Schritt ..."
else
   echo "Datenbank ist offline"
   exit 1
fi
echo "Test"

You can still write it as a one-liner if you like:

if Br3trans -u / -c -f dbstate; then echo "Datenbank ist online"; echo "Nächster Schritt"; else echo "Datenbank ist offline"; exit 1; fi
echo "Test"
2
  • Could also just replace ( with { and ) with ; } to make it a command group instead of a subshell (the semicolon is essential when going from subshell to command group).
    – mtraceur
    Commented Feb 18, 2020 at 20:12
  • @mtraceur yes, roaima also suggested that approach in this answer.
    – AdminBee
    Commented Feb 19, 2020 at 9:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .