Exit subshell by mistake

I am currently using something like this:

( false true ) && echo "OK" || echo "FAILED"; 

And it does not work. I would like the subshell to go out with an error if something doesn’t work out (in this case it’s a lie). Currently, it fails if the last command does not work.

It should exit only from the current subshell, and not from the whole script.

I pass this script on to people and I don't want them to see all the output, but still give them some kind of answer if the script was successful or not.

Edit: The commands inside the subcircuit above are just an example. I would like to run several commands inside a subshell without checking the return value after each command . Something like set -e for subshells.

Edit2: I tried adding set -e inside the subshell. Maybe I did something wrong, but that did not change the behavior of my script. This did not stop the execution or exit from the subshell with a non-0 code.

 ( set -e false echo "test" ) && echo "OK" || echo "FAILED"; 

The test prints first, and then OK. It must print FAILED due to false.

+6
source share
3 answers

This bash set -e effect is inside a conditional expression such as foo || true foo || true , known and considered a problem. I think this is a good reason to hate both set -e and shell scripts in general.

The first link makes the following sentence. It looks good with small examples, but may be less clear in the real world.

Make your own error checking by combining a number of commands with "& &" for example:

 mkdir abc && cd abc && do_something_else && last_thing || { echo error >&2; exit 1; } 

A few important notes: you do not need a backslash. You do not enter the following line. You must adhere to 80 characters per line so that everyone can see "& &" or "||" in the end. If you need to mix ANDs and ORs, group with {these curly braces} that do not spawn a sub-wrapper.

+1
source

To your edited question:

Something like set -e for subshells.

Well, you can just do set -e for the subshell.

 ( set -e my commands ) 

You cannot implicitly make only your subshells have the errexit parameter. You can do some cheats using eval , or use the subprocess as a wrapper (although the subprocess does not match the subshell), for example

 errexit_shell() { bash -e } 

but these options are not practical for various reasons, and last but not least is readability. In this case, it’s best to just adapt your entire script to use set -e , and your subshells will go for a walk.

To the original question:

Just write down the state of the part that indicates success or failure:

 ( cat teisatrt status=$? echo "true" exit "$status" ) && echo passed || echo failed 

(Of course, if all you want to know is if this file is readable, not a cat, just use test -r .)

+3
source

As you do this, you redirect the output from the entire subshell to / dev / null, so you will never see your "true" echo. You must move the redirection inside the subshell to the command that you really want. To exit the subshell when cat fails, you will need to check the failure after cat . If you do not, then, as you have already noted, its return code is destroyed by the following statement. So something like this:

 echo "Installing App" ( cat teisatrt &> /dev/null || exit 1 echo "true" ) && echo "OK" || echo "FAILED"; 
0
source

Source: https://habr.com/ru/post/986170/


All Articles