为什么这个shell脚本不起作用?

时间:2013-10-12 01:35:36

标签: linux bash shell sh zsh

我注意到find -execdir不可移植,所以我决定找到一种只使用find -exec来实现相同效果的便携方法。要做到这一点,必须能够确定'find'找到的'/'目录的路径是否包含任何符号链接,如果有,则拒绝遍历它。我写了一个小脚本来确定给定的路径是否包含符号链接,但无论我给它什么,它似乎总是返回代码1。没有打印任何东西的命令,除非我给它一个非目录,在这种情况下,第一个printf命令会触发。

#!/bin/sh -e
# If any commands fail, the script should return a nonzero status
[ -d "$1" ] || printf "%s is not a directory" "$1" && exit 1  # Tests if argument is a directory
cd "$1" || echo "Could not change directory" && exit 1 # If it is a directory, goes to it
until [ "$PWD" = '/' ] # Loop until root directory reached 
do
    cd .. || echo "Could not change directory" && exit 1 # Go to parent directory
    [ -d "$PWD" ] || printf "%s is not directory" "$PWD" && exit 1 # Check that this is a directory
done
echo "Given an okay directory"
exit 0

3 个答案:

答案 0 :(得分:1)

在bash中(与c-like语言不同)&&||具有相同的优先级。这意味着你的

command || echo error && exit 1

语句被解释为

{ command || echo error } && exit 1

由于echo很可能成功,即使command没有成功,第一个块也会成功,并且exit语句将被执行。

答案 1 :(得分:1)

对于每个条件行,您应该使用()将失败括起来。例如:

[ -d "$1" ] || (printf "%s is not a directory" "$1" && exit 2)

我将进一步解释@Kevin所写的内容:如果第一个语句失败([ -d ]),则执行第二个语句。由于第二个成功(仅在极少数情况下printf失败),然后执行最后一个语句。在这种格式中,只有在前两个失败的情况下才会执行exit语句。如果它不是目录,则会获得printf和exit。如果它是一个目录,第一个||变为真,并且bash不打扰测试下一个(printf),并再次转到&&,即退出。将失败包括在内会阻止这种情况发生。

答案 2 :(得分:0)

您可以检查$1是否不是具有反! -d的目录,并使用if; then在返回true后执行命令。

#!/bin/sh -e
# If any commands fail, the script should return a nonzero status
if [ ! -d "$1" ]
then
    printf "%s is not a directory" "$1"
    exit 1 # Tests if argument is a directory
fi
cd "$1" # If it is a directory, goes to it
until [ "$PWD" = '/' ] # Loop until root directory reached
do
    cd .. # Go to parent directory
done
echo "Given an okay directory"
exit 0