4

what is preferred between

if ! [ ... ]; then

and

if [ ! ... ]; then

actually they do the same result, is there a preferred syntax? in the former syntax the evaluated not is the shell builtin, while in the latter the not is the test one, does it make any difference?

  • The shell will have test/[/[[ builtin too. I'd say whatever makes your code easier to read – glenn jackman Oct 5 '16 at 13:48
  • The first one looks more familiar to me because you use it with other commands than test too. I don't remember many use cases where I've used ! as argument for test. The most often used expressions have their own opposite expression. – rudimeier Oct 5 '16 at 14:10
4

There's a portability consideration.

The ! keyword is POSIX but not Bourne while ! has been supported by the [/test command from the start.

So [ ! ... ] is more portable than ! [ ... ].

Otherwise, as long as you don't use the deprecated -o and -a binary operators, they should be equivalent (if we put aside the parsing bugs in some old test implementations).

Actually, in the Bourne shell, to do

if ! cmd1; then
  cmd2
fi

You had to do:

if cmd1; then
  :
else
  cmd2
fi

(or use cmd1 || cmd2, though that could result in a different exit status in the end).

  • I wasn't aware that -o and -a were deprecated inside single square brackets or with test, my man test doesn't say that they are. Are there alternatives (still using single square brackets or test)? – gogoud Oct 5 '16 at 15:03
  • 1
    @gogoud, yes using -o and -a make for unreliable expressions, use [ ... ] && [ ... ]. See the POSIX spec for the test utility – Stéphane Chazelas Oct 5 '16 at 15:34
0

[ … ] is equal to test …, so ! [ … ] is equal to ! test …. That means, you negate the result of the command test. In this case, ! is a shell command.

From info bash, e.g. in section «pipelines»:

If the reserved word `!' precedes the pipeline, the exit status is the logical negation of the exit status as described above.

On the other side, [ ! … ] means test ! …. That means, you negate an expression within test. See ! in man test:

   ! EXPRESSION
          EXPRESSION is false

So it can have a different meaning. If you have complex expressions, the negation may only apply to a part.

It is up to you, what you prefere.

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.