-3

I'm refactoring my scripts and am trying to convert all if cmd; then fi; statements to if [[cmd]]; then fi. I know how to convert it by invoking the command in previous line and using its exit code in current line, but I want to know how to do it inline.

Example:

# I have this

if grep "some-string" some_file.txt > /dev/null; then
  echo "non zero exit status"
fi
# I know how to do this

$(grep "some-string" some_file.txt > /dev/null)
if [[ $? -ne 0 ]]; then
  echo "non zero exit status"
fi
# I want to know how to do something like this?

if [[ grep "some-string" some_file > dev/null ]]; then
  echo "non zero exit status"
fi

Please let me know how to do inline execution and check of status code for a command inside if [[...]]; then fi statement?

I'm referencing bash from this and trying to follow styling from this

oguz ismail
  • 1
  • 16
  • 47
  • 69
sampath.xyz
  • 150
  • 1
  • 7
  • 2
    Don't. The `if grep ...` version you have now is correct and idiomatic. You use `[[ ]]` when you want to test a conditional expression, not when you want to see whether a command succeeded (unless you stored the exit status of the command in a variable, in which case you need a conditional expression to check the value of the variable). – Gordon Davisson May 31 '21 at 10:09
  • 1
    What?! `[[ grep ...` doesn’t make any sense. `if grep ...` is the correct way to do it. What part of that style guide makes you think that you need to refactor it? – Biffen May 31 '21 at 10:09
  • 2
    (OT: The refactoring that code needs it removing `> /dev/null` and adding `-q`.) – Biffen May 31 '21 at 10:10
  • @Biffen [this part in the style guide](https://google.github.io/styleguide/shellguide.html#s6.3-tests) is what was confusing me. I'm not that versed in shell-scripting as I'm using shell. The `-q` flag for grep is helpful though. – sampath.xyz May 31 '21 at 10:16
  • 2
    @rsampaths16 That section does not apply to commands’ exit codes. It just says to use `[[` over `test` (and other ways to call `test`, e.g. `[`). You’re not using `test`, so the rule doesn’t apply. – Biffen May 31 '21 at 10:20

1 Answers1

2

This does not make sense:

if cmd ; ...

would run cmd and then branch depending on the exit status of cmd.

Similarily,

if [[ cmd ]]; ....

runs the command [[...]] and branch accordingly. It does not run cmd.

Actually, as long as you are only interested in knowing whether the exit status is zero or not, I see no reason why you should fiddle around with $?. Things are different if you have several exit status values to distinguish. For example:

grep foo bar; status=$?
if (( status == 0 ))
then
   # actions where grep found the pattern
elif (( status == 1 ))
   # actions where grep did not find the pattern
else
   # actions where grep encountered a serious problem
fi

In this case, store the exit code immediately after invoking your command into some variable, and process it later with if or case or whatever you need.

user1934428
  • 19,864
  • 7
  • 42
  • 87