Bash file system directory test trickery
Assuming that the folders exist in the script below, can someone tell my why this is not working? I escape the spaces extra for the test to work but somehow it does not like it with no error...
#!/bin/bash
Base='/tmp/'
Sub='one space/another space/'
declare -a ASub
for argR in "${Sub[@]}"
do
Sub+=($(printf %q "$argR"))
done
clear
echo -n $Base
if [ -d $ExBase ]
then
e开发者_开发知识库cho "...OK"
else
echo "...FAIL"
fi
BaseAndSub=$Base$Sub
echo -n $BaseAndSub
if [ -d "$BaseAndSub" ]
then
echo "...OK"
else
echo "...FAIL"
fi
exit 0
Lots wrong with that script. ASub
is declared and never used. ExBase
is never declared but used.
I guess this is the main problem: if [ -d $ExBase ]
Since ExBase
is empty and unset, the shell sees this: if [ -d ]
I would have expected a syntax error but apparently the shell sees "-d" as just a non-empty string, and is therefore true.
As @glenn said, there's lots wrong here; ASub
is declared but not used, Sub
is sometimes used as a string variable sometimes as an array, ExBase
is used without being set, ...
The fundamental problem, though, is that you're going through a lot of unnecessary (and sometimes destructive) work in an attempt to handle spaces in the filename, when all that's necessary is to use double-quotes around everything that might contain spaces. Arrays are great for storing lists of filenames (each of which might have spaces) or command strings (that might have spaces in their arguments), but in this case you have a single filename so that's not needed. Adding quotes (printf %q
) is almost never useful, it just means you'll be looking for files with actual quotes/escapes/whatever in the names.
Here's my rewrite with the irrelevant stuff stripped out, and double-quotes added in a couple of places. I also changed to the more standard convention of not including trailing slashes in the filenames, so putting Base and Sub together is "$Base/$Sub"
not just "$Base$Sub"
. It seems to work fine for me:
#!/bin/bash
Base='/tmp'
Sub='one space/another space'
clear
echo -n "$Base"
if [ -d "$Base" ]
then
echo "...OK"
else
echo "...FAIL"
fi
BaseAndSub="$Base/$Sub"
echo -n "$BaseAndSub"
if [ -d "$BaseAndSub" ]
then
echo "...OK"
else
echo "...FAIL"
fi
exit 0
BTW, when trying to troubleshoot bash scripts, it's very helpful to use the -x option (either with set -x
, or use #!/bin/bash -x
as your shebang). This makes bash print each command before executing it -- with parameters expanded to show exactly what's happening.
精彩评论