Gerardo Zinno Gerardo Zinno - 27 days ago 10
Bash Question

Bash script takes wrong conditional path for unknown reason

I have the following bash script that should list the folders in the same directory, and let me choose a folder to move in, and then list its content.

#!/bin/bash

PS3="Scelta?"

select dest in $( command ls -aF | grep "/" ); do
if [ -d $dest ]; then
cd $dest
echo "$0 : changed to $dest"
ls
break

else
echo "$0 : wrong choice" 1>$2
fi
done


the path of the script is something like


/Users/myName/Documents/GitHub/SO/Exercise4


and this is the content of the Exercise4 dir


1/ 2/ 3/ 4/ 5/ select.sh


when I run the script it prompts me something like

1) ./
2) ../
3) 1/
4) 2/
5) 3/
6) 4/
7) 5/
Scelta? 


If I choose an option between 1 and 7 the script works, but when I input a number out of that range, instead of echoing me "wrong choice" it lists me my home directory and I can't figure out why

Answer Source

Why This Happens

Consider:

dest=
[ -d $dest ]

What does this do? It runs the command:

[ -d ]

What does that do? It's shorthand for:

[ -n "-d" ]

...which is to say, it checks whether -d is empty, which it isn't, so the result is true.


How To Stop It

  1. Use More Quotes

    Consider this instead:

    dest=""
    [ -d "$dest" ]
    

    When run, it doesn't invoke [ -d ]; instead, it runs [ -d '' ]: The quotes prevented the expansion results from being split into a different number of strings than they started as.

  2. When On Bash, Consider The Extended Test Form

    [[ -d $dest ]]
    

    ...suppresses string-splitting and glob expansion, so it works even without quotes.