4

I have a question about the structure of conditional statements that are to be used at the bash command line.

This question shows:

if [ -z "${VAR}" ]; then echo "VAR is unset or set to the empty string"

Here, the it appears that the then is only being called when the variable VAR does not exist. This is confirmed from here.

However, for directories, this question shows:

if [ -d $directory_name ]; then echo "Directory already exists"

Here, it would appear that the then is only being called when the variable directory_name does exist. This is confirmed from here (scroll down to -d).

My problem: I recently tried to check if a variable existed or not. When I tried to apply the same logic to directories, I was surprised that it cannot be done. Here is what I tried:

dir_full_path='/mnt/iso'
if [ -d $dir_full_path ]; then echo 'Directory does not exist'; else echo 'Does exist'; fi

When I ran these 2 lines, the directory path /mnt/iso did not exist. So I expected the conditional to return Directory does not exist. Instead, it did the opposite and it returned Does exist.

Question: This is quite confusing since it seems like the same structure of a conditional cannot be used for a directory and for a variable. Is this true? If so, then is this difference documented somewhere?

Community
  • 1
  • 1
edesz
  • 8,579
  • 17
  • 58
  • 103
  • I don't see any issue with the 2 line approach, except that it is safer to enclose the variable in double quotes (so that you don't fall into a syntax issue if the variable evaluates to nothing), thus: if [ -d "$dir_full_path" ]; then ... – codeforester Nov 15 '16 at 01:49
  • 1
    `-d` tests if its argument is a directory. `-z` tests if its argument is an empty string. – Barmar Nov 15 '16 at 01:59
  • 1
    You seem to have answered your own question: **the then is only being called when the variable directory_name does exist.** Why do you expect it to work differently for `-d $dir_full_path`? – Barmar Nov 15 '16 at 02:01
  • I think that is what confused me. `-z` is checking for an empty string. I thought that `-d` would analogoously mean empty directory (i.e. directory does not exist). I used this logic when I set up the conditional and this is what has given me problems. Thanks for your above comment. It helped me. – edesz Nov 15 '16 at 02:08
  • Why would `-d` check for empty directory? It just checks for a directory. – Barmar Nov 15 '16 at 02:45
  • 1
    Each option to `test` checks for something specific, and the documentation tells you exactly what it looks for. There's no logic that makes them similar to each other. – Barmar Nov 15 '16 at 02:46
  • @Barmar: I was incorrectly thinking, in the same way that "`-z` tests if its argument is an empty string", that `-d` checked if the directory was unset (undefined or non-existent). This was my error that led to a lot of my confusion. Thanks for clearing it up though. – edesz Nov 15 '16 at 04:25

1 Answers1

3

Here is the proper use of these commands, which can be found by running help test:

if [ -z "$j" ]
then
  echo '$j is empty'
fi

if [ -n "$j" ]
then
  echo '$j is not empty'
fi

if [ -d /mnt/iso ]
then
  echo '/mnt/iso is a directory'
fi
Steven Penny
  • 82,115
  • 47
  • 308
  • 348