我想写一个bash函数,检查文件是否具有某些属性并返回true或false。然后我可以在我的脚本中的“如果”中使用它。但是我应该返回什么呢?

function myfun(){ ... return 0; else return 1; fi;}

然后我这样使用它:

if myfun filename.txt; then ...

当然这行不通。如何才能做到这一点呢?


当前回答

下面是一些测试用例的好例子。

对于基本函数,在方法的最后一行调用true/false,或者使用true;返回以提前退出。

function is_true() { true; }

if is_true; then echo 'true is true'; fi
if ! is_true; then exit; else echo '! true is ! true'; fi

function is_false() { false; }

if ! is_false; then echo 'false is false'; fi
if is_false; then exit; else echo '! false is ! false'; fi

如果不能立即返回,则将返回值存储在变量中。使用(正确;在设置变量时Echo $?)这也适用于嵌套函数(见下一节)。

function from_var() {
        local input=$1
        local my_var
        if ((input == 1)); then
                my_var=$(true; echo $?)
        else
                my_var=$(false; echo $?)
        fi
        echo 'ignore this line'
        (exit $my_var)
}

if from_var 1; then echo "return true is true"; else exit; fi
if from_var 0; then exit; else echo "return false is false"; fi

如果需要存储返回bool类型的函数调用的结果,可以使用相同的技术,但是将调用的输出通过管道传输到/dev/null,或者结果也可能包含来自echo或其他命令的字符串。注意if语句中的(exit $rval)可以让您正确地解释返回值。(其他方法如if (($rval))或if [$rval]将不能正常工作。

# Return a truthy result
rval=$(from_var 1 >/dev/null; echo $?)
if (exit $rval); then echo "return true as variable is true"; else exit; fi

# Return a falsy result
rval=$(from_var 0 >/dev/null; echo $?)
if (exit $rval); then exit; else echo "return false as variable is false"; fi

这段代码的完整输出是:

true is true
! true is ! true
false is false
! false is ! false
ignore this line
return true is true
ignore this line
return false is false
return true as variable is true
return false as variable is false

如果不希望使用> /dev/null抑制函数内的输出,则重写以首先调用该函数。

from_var 0; rval="$?"

其他回答

重写一下可能有用 函数myfun(){…返回0;否则返回1;Fi;}作为这个函数myfun(){…返回;其他假;fi;}。也就是说,如果函数中的最后一条指令为false,则整个函数的结果为false,但无论如何都会返回结果为true的中断函数。我相信至少对我的bash解释器来说是这样的。

在只使用选项-d检查目录时要小心! 如果变量$1为空,检查仍然会成功。当然,还要检查变量是否为空。

#! /bin/bash

is_directory(){

    if [[ -d $1 ]] && [[ -n $1 ]] ; then
        return 0
    else
        return 1
    fi

}


#Test
if is_directory $1 ; then
    echo "Directory exist"
else
    echo "Directory does not exist!" 
fi

为什么你要关心我说什么,尽管有350+个赞的答案

不是0 =真1 =假。它是:零意味着没有失败(成功),非零意味着失败(类型N)。

虽然所选的答案在技术上是“正确”的,但请不要在代码中返回1**为false。它会有一些不幸的副作用。

有经验的开发人员会把你当成业余爱好者(原因如下)。 有经验的开发人员不会这样做(原因如下)。 它很容易出错。

即使是经验丰富的开发人员也会将0和1分别误认为是假的和真的(基于上述原因)。

它需要(或会鼓励)无关紧要和荒谬的评论。 它实际上不如隐式返回状态有用。

学习一些bash

bash手册说(重点是我的)

返回[n] 导致shell函数停止执行并将值n返回给调用者。如果不提供n,则返回值为函数中执行的最后一个命令的退出状态。

因此,我们不必用0和1来表示真和假。事实上,他们这样做本质上是微不足道的知识,只对调试代码、面试问题和让新手感到惊讶有用。

bash手册还说

否则,函数的返回状态是最后执行的命令的退出状态

bash手册还说

($ ?)展开到最近执行的前台管道的退出状态。

哇,等。管道?让我们再看一遍bash手册。

管道是由一个控制操作符“|”或“|&”分隔的一个或多个命令的序列。

是的。他们说1号命令是一条管道。因此,这三句话的意思是一样的。

$ ?告诉你最后发生了什么。 它会冒出来。

我的答案

虽然@Kambus演示了这样一个简单的函数,根本不需要返回。我认为 与大多数读者的需求相比,这是不切实际的简单。

为什么回来?

如果一个函数要返回它最后一个命令的退出状态,为什么要使用return呢?因为它会导致函数停止执行。

在多种情况下停止执行

01  function i_should(){
02      uname="$(uname -a)"
03
04      [[ "$uname" =~ Darwin ]] && return
05
06      if [[ "$uname" =~ Ubuntu ]]; then
07          release="$(lsb_release -a)"
08          [[ "$release" =~ LTS ]]
09          return
10      fi
11
12      false
13  }
14
15  function do_it(){
16      echo "Hello, old friend."
17  }
18
19  if i_should; then
20    do_it
21  fi

我们这里有…

第04行是一个显式的[-ish]返回true,因为&&的RHS只有在LHS为真时才会执行

第09行返回true或false,匹配第08行的状态

第13行返回false,因为第12行

(是的,这可以打高尔夫球,但整个例子是人为的。)

另一种常见模式

# Instead of doing this...
some_command
if [[ $? -eq 1 ]]; then
    echo "some_command failed"
fi

# Do this...
some_command
status=$?
if ! (exit $status); then
    echo "some_command failed"
fi

Notice how setting a status variable demystifies the meaning of $?. (Of course you know what $? means, but someone less knowledgeable than you will have to Google it some day. Unless your code is doing high frequency trading, show some love, set the variable.) But the real take-away is that "if not exit status" or conversely "if exit status" can be read out loud and explain their meaning. However, that last one may be a bit too ambitious because seeing the word exit might make you think it is exiting the script, when in reality it is exiting the (...) command group subshell.


**如果你坚持使用return 1来表示false,我建议你至少使用return 255来代替。这将导致您未来的自己或任何其他必须维护您的代码的开发人员质疑“为什么是255?”这样他们至少会集中注意力,有更好的机会避免犯错。

myfun(){
    [ -d "$1" ]
}
if myfun "path"; then
    echo yes
fi
# or
myfun "path" && echo yes

出于代码可读性的考虑,我认为返回true/false应该:

在一条线上 成为一个命令 容易记住 提到关键字return后跟另一个关键字(真或假)

我的解决方案是返回$(true)或返回$(false)如下所示:

is_directory()
{
    if [ -d "${1}" ]; then
        return $(true)
    else
        return $(false)
    fi
}