0

Having this simple line:

user@Host:~$ ls -> fileA fileB
user@Host:~$ [[ -d $dir_name ]] && rm * # $dir_name does not exist, empty variable
user@Host:~$ ls -> fileA fileB  #does not delete anything, as expected

user@Host:~$ [ -d $dir_name ] && rm *
user@Host:~$ ls ->  #empty, although there is a test, all files are deleted, why?

I know double bracket [[ is an extension of bash (or introduced by ksh), but why does not standard test turn off, when the obvious exit status is 0 in example above?

  • 1
    This is a classic example of Always-Quote-Your-Variable – Jetchisel Apr 12 at 9:07
  • 1
    You already have an answer below. – Jetchisel Apr 12 at 9:15
  • 2
  • 2
    @Herdsman "In general, it is the same" leads to bugs. – Kamil Maciorowski Apr 12 at 9:38
  • 1
    @Jetchisel: Fortunately, bash 2.0 was released in 1996, so by now all distributions (including CentOS) should have it available. – user1686 Apr 12 at 9:44
2

The correct usage would be [ -d "$dir_name" ].

Normally, unquoted variables are subject to word-splitting: if $dir_name contains spaces it will expand to multiple arguments in the resulting command's argv[] array; and if it's an empty string it will produce no args at all. The same rules apply to [, which is nothing more than a built-in command (and indeed a standalone executable as well).

So your second command is not the same as [ -d "" ] – it actually expands to [ -d ]. Due to different arg count, it becomes a completely different expression – the -d no longer indicates a "directory exists" test, but instead is itself used as a string parameter for the "string argument is non-empty" test (like [ foo ]), which of course succeeds.

However, these rules do not apply to [[, which receives special treatment from the shell's parser. Variable expansion inside [[ works differently – in many cases the argument is implicitly "double-quoted", so [[ -d $foo ]] and [[ -d "$foo" ]] are equivalent. That's where the difference comes from.

See also:

| improve this answer | |

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.