0

I have below lines in my script and it works fine as of now:

URL="$(hostname -f | grep -q "\.dev\." && echo "$URL_1" || echo "$URL_2")"
FILE="$(hostname -f | grep -q "\.dev\." && echo "file.init.proc" || echo "file.init.test")"
curl --fail -o "$TEMPFILE" "$URL" && if ! grep -q "$TEST_IPD" "$TEMPFILE"; then echo "ipaddress missing in the file" || return 2; else mv -- "$TEMPFILE" "$CONFIG_DIR/$FILE"; rm -f -- "$TEMPFILE"; fi
"line 4- something here"
"line 5- something here"

But earlier there was some problem in my URL and FILE line and because of which my curl line failed and for some reason still line 4 and line 5 got executed and I don't want those lines to be executed.

Let's say for some reason if I am not able to extract URL or FILE variable then if my curl line fails then I don't want line 4 and line 5 to be executed at all. Basically if my curl line fails for whatever reason I don't want line 4 or line 5 to be executed at all.

flash
  • 1,455
  • 11
  • 61
  • 132
  • 1
    It looks like you already know how to use an `if` statement. What is the particular problem you're having? – larsks Jan 22 '20 at 19:51
  • problem is how to avoid executing line 4 and line 5. I thought `--fail` in `curl` will do exactly but it doesn't work or maybe it is working differently? – flash Jan 22 '20 at 20:01

2 Answers2

3

Let's clean this up a bit.

if hostname -f | grep -qF '.dev.'; then
    URL=$URL_1
    FILE=file.init.proc
else
    URL=$URL_2
    FILE=file.init.test
fi

if curl --fail -o "$TEMPFILE" "$URL"; then
    if ! grep -q "$TEST_IPD" "$TEMPFILE"; then
        echo "ipaddress missing in the file" >&2
        return 2
    else
        mv -- "$TEMPFILE" "$CONFIG_DIR/$FILE" && rm -f -- "$TEMPFILE"
    fi
else
    "line 4- something here"
    "line 5- something here"
fi

--fail just causes curl to exit if something goes wrong; it has no effect on the shell that executed curl. Try to avoid using && and || for anything other than short commands, and never use ... && ... || ... in place of a proper if statement.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • In my case `URL` and `FILE` is not a global variable so curl line will still works in your example? – flash Jan 22 '20 at 20:11
  • BTW, it's safest to use lower- or mixed-case variable names (e.g. `url` instead of `URL`) to avoid conflicts with the various all-caps names with special meanings or functions. – Gordon Davisson Jan 22 '20 at 23:16
0

There are several ways to stop or continue after a failed command.
Here are some examples:


Include the command as if condition maybe the best way

$ if echo foo; then echo bar; fi  
foo  
bar    

Inspect the exit code to know the result of a given command (the standard is to return a 0 exit code in case of success and a variable code from 1 to 255 in case of error) but as @Charles Duffy said

this is an antipattern because it introduces complexity that wouldn't exist if you didn't require the exit status to be recorded at all.

More info here

$ echo foo  
$ echo $?  
0  

So you can do something like:

$ echo foo  
foo
$ if [[ $? == 0 ]]; then echo bar; fi  
bar

Using exit code and arithmetic mode
Testing for success

$ if ! (($?)); then echo bar; fi  
bar  

Testing for failure

$ if (($?)); then echo bar; fi   

Using && ||

$ echo foo && echo bar || echo baz
foo  
bar

Speaking about your question, simplify and do something like this:

if curl -o "$TEMPFILE" "$URL"; then  
  echo SUCCESS   
  echo "Here's the logic of your 4 and 5 line or whatever you want."  
else  
  echo FAIL  
  echo "Maybe you should exit with an error code, like this "  
  exit 1  
fi  

exit 0
Roberto Manfreda
  • 2,345
  • 3
  • 25
  • 39
  • 1
    **Do not** encourage people to inspect `$?` manually -- `foo; if [ $? -eq 0 ]; then ...` has no advantages whatsoever (and several disadvantages, including incompatibility with `set -e`, fragility when code is modified, reduced readability, etc) compared to `if foo; then ...` – Charles Duffy Jan 22 '20 at 21:01
  • 3
    See [Why is testing “$?” to see if a command succeeded or not, an anti-pattern?](https://stackoverflow.com/questions/36313216/why-is-testing-to-see-if-a-command-succeeded-or-not-an-anti-pattern) – Charles Duffy Jan 22 '20 at 21:03
  • In my opinio the best way is to include the command as if condition. I was doing a list of possibilities, I didn't know that using it was an antipattern! And yes you are right, it adds some complexity that can be avoided. Anyway thanks for writing it here so I can edit the answer to improve it. – Roberto Manfreda Jan 22 '20 at 21:12
  • @GordonDavisson sorry, I was wrong. I corrected the third example :) ty – Roberto Manfreda Jan 23 '20 at 00:11