开发者

Bash file system directory test trickery

开发者 https://www.devze.com 2023-04-10 20:22 出处:网络
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...

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号