2

(NOTE: There is a very similar question, asked yesterday oddly enough, but it doesn't cover the main syntaxes I'm concerned with. If I were to update the other question to include them it might render the answers no longer valid, so I'll focus here on what was missed in the other question. Anyone who wants the whole picture should look at both questions and their accepted answers.)

I typically write my if statements as follows:

if [[ -z "$SOMETHING" ]]; then
  # blah blah blah
fi

which works well for me under Bash and Z Shell, but I recently came across a syntax which drops the square brackets entirely:

if command -v given-command > /dev/null 2>&1; then
  echo given-command is available
else
  echo given-command is not available
fi

Is the version without any brackets portable? How does it compare to the options presented here?

Is my standard version mainly only supported on Bash and Z Shell (like the [[ -w /home/durrantm ]] && echo "writable" version mentioned on that other question)?

  • Yes, I've update my (referenced) question to only be about [ vs [[ vs test and now this question can just be about if...fi portability. – Michael Durrant Nov 17 '14 at 17:50
  • @MichaelDurrant: excellent. After reading muru's answer I realized your question (and maybe mine too) dealt with both issues without specifically delineating them. I thought of commenting to that effect there, but I'm glad you noticed it too and took action first. Thanks! – iconoclast Nov 17 '14 at 18:36
  • Is there some shell in which $"SOMETHING" works, or is that just a typo for "$SOMETHING"? – Scott Jul 15 '16 at 19:59
  • @Scott: pretty sure that was a typo... at least I can't see any reason for it other than that. – iconoclast Jul 15 '16 at 21:22
1

Yes, your standard version is not POSIX-standard, as the question you linked to notes. However, the following is:

if some-command args; then ...

I'd say this is the only portable form of if, since, this is what if is all about. if does something if some-command (which can be a function, a shell builtin, or an executable1) returns 0 for the arguments and input it is run with.

When you run if [ ] or if [[ ]], [ ] and [[ ]] are programs or shell builtins which return 0 if the condition tests true. If you convert [ to test, you'll see that you're always running the form without the brackets:

if [ ... ]
# same as 
if /bin/test ...

1To be more precise, let's look at how the if construct is defined:

The if command shall execute a compound-list and use its exit status to determine whether to execute another compound-list.

The format for the if construct is as follows:

if compound-list 
then
    compound-list
[elif compound-list 
then
    compound-list] ...
[else
    compound-list]
fi

Note that a compound list is not the same as a compound command.

  • Aha: now the syntax actually makes sense... I don't think anyone dealt with if /bin/test as one of the examples in the answers to the other question. Your answer seems to fill in the missing details quite nicely. Thanks! – iconoclast Nov 17 '14 at 17:40
  • @iconoclast That could be because test is also a shell-builtin, and so if test would always use the builtin. That's probably why nobody covers the case of /bin/test. – muru Nov 17 '14 at 17:45
  • I didn't notice anyone dealing with if test either... but perhaps I just missed it. – iconoclast Nov 17 '14 at 18:38
  • @iconoclast There's a cameo in this answer (fourth-from-last bullet point). – muru Nov 17 '14 at 18:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.