简体   繁体   English

为什么此Shell脚本不起作用?

[英]Why does this shell script not work?

I have noticed that find -execdir is not portable, so I decided to find a portable way of using just find -exec to achieve the same effect. 我注意到find -execdir不是可移植的,因此我决定找到一种仅使用find -exec来实现相同效果的可移植方式。 To do this, one must be able to determine if the path to a directory from '/' found by 'find' contains any symbolic links, and refuse to traverse it if it does. 为此,必须能够确定'find'从'/'指向目录的路径是否包含任何符号链接,如果存在,则拒绝遍历该符号链接。 I wrote a small script to determine if a given path contains symbolic links, but it seems to always return code 1, no matter what I give it. 我写了一个小脚本来确定给定的路径是否包含符号链接,但是无论我给出什么,它似乎总是返回代码1。 No command that prints anything fires, except if I give it a non-directory, in which case the first printf command fires. 没有命令输出任何东西,除非我给它提供了一个非目录,在这种情况下,第一个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

In bash (unlike c-like languages) && and || 用bash(与类似c的语言不同) &&|| have the same precedence. 具有相同的优先级。 That means your 那意味着你

command || echo error && exit 1

statements are interpreted as 语句被解释为

{ command || echo error } && exit 1

Since echo will most likely succeed even if command doesn't, the first block will succeed and the exit statement will be executed. 因为即使command不执行, echo也很可能成功,所以第一个块将成功执行,并且exit语句将被执行。

For each condition line, you should enclose the failure with () . 对于每个条件行,都应将失败包含在() For example: 例如:

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

I'll explaun further what @Kevin wrote: If the first statement fails (the [ -d ] ), then the second statement is executed. 我将进一步说明@Kevin编写的内容:如果第一条语句失败( [ -d ] ),则第二条语句将执行。 Since the second succeeds (only in rare cases does printf fails), then the last statement is executed. 由于第二个成功(仅在极少数情况下printf失败),因此将执行最后一条语句。 In this format, the exit statement will not get executed ONLY if BOTH the first two failed. 以这种格式,只有前两个都失败,才不会执行exit语句。 In case it is not a directory, you get a printf and an exit. 如果它不是目录,您将获得一个printf和一个出口。 In case it is a directory, the first || 如果是目录,则第一个|| becomes true, and bash doesn't bother testing the next one (printf), and goes to the && , which is the exit, again. 变为true,bash不再费心测试下一个(printf),而是再次转到&& ,即出口。 Enclosing the failures as one will prevent this. 将故障封闭为一个将防止这种情况。

You can check if $1 is not a directory with the inverse ! -d 您可以检查$1是否不是带有相反的目录! -d ! -d and use if; then ! -d并使用if; then if; then to execute commands after it returns true. 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM