从Bash函数返回一个布尔值

时间:2011-03-25 11:39:09

标签: bash shell boolean

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

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

然后我像这样使用它:

if myfun filename.txt; then ...

当然这不起作用。如何实现这一目标?

10 个答案:

答案 0 :(得分:281)

使用0表示true,使用1表示false。

样品:

#!/bin/bash

isdirectory() {
  if [ -d "$1" ]
  then
    # 0 = true
    return 0 
  else
    # 1 = false
    return 1
  fi
}


if isdirectory $1; then echo "is directory"; else echo "nopes"; fi

修改

来自@ amichair的评论,这些也是可能的

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


isdirectory() {
  [ -d "$1" ]
}

答案 1 :(得分:110)

为什么你应该关心我说的话,尽管有250多个upvote答案

不是0 = true1 = false。它是:零表示没有失败(成功) 非零表示失败(类型N)

虽然selected answer在技术上是“真实的”,请不要在您的代码中添加return 1 ** false 。它会有几个不幸的副作用。

  1. 有经验的开发人员会将您视为业余爱好者(原因如下)。
  2. 有经验的开发人员不这样做(出于以下所有原因)。
  3. 容易出错。
    • 即使是经验丰富的开发人员也可以分别将0和1误认为是假的(原因如上)。
  4. 它需要(或将鼓励)无关的和荒谬的评论。
  5. 它实际上没有隐含的返回状态。
  6. 学习一些bash

    bash manual说(强调我的)

      

    return [n]

         

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

    因此,我们不必使用0和1来表示True和False。他们这样做的事实本质上是微不足道的知识,仅用于调试代码,面试问题和吹响新手的思想。

    bash手册also says

      

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

    bash手册also says

      

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

    哇,等等。管道?让turn to the bash manual再一次。

      

    管道是一个或多个命令的序列,由一个控制运算符'|'或'|&'分隔。

    是。他们说1命令是一个管道。因此,所有这三个引用都在说同样的事情。

    • $?告诉你最后发生了什么。
    • 气泡起来。

    我的回答

    所以,虽然@Kambus demonstrated具有如此简单的功能,但根本不需要return。我认为  与大多数阅读此内容的人的需求相比,这是不切实际的简单。

    为什么return

    如果函数要返回其最后一个命令的退出状态,为什么要使用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返回与行08

    的状态匹配的true或false

    由于行13

    ,行12返回false

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

    另一种常见模式

    # 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
    

    请注意设置status变量如何揭开$?的含义。 (当然你知道$?意味着什么,但是那些知识不足你的人有一天会把它当作谷歌。除非你的代码进行高频交易,show some love,设置变量。)但真实的外卖是“如果不存在状态”或相反“如果退出状态”可以大声朗读并解释其含义。 但是,最后一个可能有点过于雄心勃勃,因为看到单词exit可能会让你认为它正在退出脚本,而实际上它正在退出$(...)子shell

    **如果您绝对坚持使用return 1为假,我建议您至少使用return 255。这将导致您未来的自我,或任何其他必须维护您的代码的开发人员质疑“为什么是255?”然后他们至少会注意并有更好的机会避免错误。

答案 2 :(得分:30)

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

答案 3 :(得分:13)

使用选项-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

答案 4 :(得分:4)

出于代码可读性的原因,我相信返回true / false应该:

  • 在同一行
  • 成为一个命令
  • 容易记住
  • 提及关键字return,后跟另一个关键字(truefalse

我的解决方案是return $(true)return $(false),如下所示:

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

答案 5 :(得分:2)

true之前紧接使用falsereturn命令,然后在不带参数的情况下使用returnreturn将自动使用上一个命令的值。

return提供参数是不一致的,如果您未使用1或0,则类型特定并且容易出错。并且如先前的评论所述,此处使用1或0并不是实现此功能的正确方法

#!/bin/bash

function test_for_cat {
    if [ $1 = "cat" ];
    then
        true
        return
    else
        false
        return
    fi
}

for i in cat hat;
do
    echo "${i}:"
    if test_for_cat "${i}";
    then
        echo "- True"
    else
        echo "- False"
    fi
done

输出:

$ bash bash_return.sh

cat:
- True
hat:
- False

答案 6 :(得分:1)

如果你改写它可能会有用 function myfun(){ ... return 0; else return 1; fi;} function myfun(){ ... return; else false; fi;}。也就是说,如果false是函数中的最后一条指令,则会得到整个函数的错误结果,但无论如何return中断函数的结果都是真实的。我相信至少对我的bash口译员来说这是真的。

答案 7 :(得分:1)

我发现测试函数输出的最短形式就是

do_something() {
    [[ -e $1 ]] # e.g. test file exists
}

do_something "myfile.txt" || { echo "File doesn't exist!"; exit 1; }

答案 8 :(得分:0)

我遇到了一个绊脚石(尚未明确提及?)。也就是说,不是如何返回布尔值,而是如何正确地对其进行求值!

我试图说if [ myfunc ]; then ...,但这完全是错误的。请勿使用括号! if myfunc; then ...是做到这一点的方法。

与@Bruno和其他人重申的一样,truefalse命令,而不是值!这对于理解shell脚本中的布尔值非常重要。

在这篇文章中,我使用布尔值变量https://stackoverflow.com/a/55174008/3220983进行了解释和演示。我强烈建议您检查一下,因为它是如此紧密相关。

在这里,我将提供一些从函数返回和评估布尔值的示例:

此:

test(){ false; }                                               
if test; then echo "it is"; fi                                 

不产生回声输出。 (即false 返回否)

test(){ true; }                                                
if test; then echo "it is"; fi                                 

产生:

it is                                                        

(即true 返回 true)

test(){ x=1; }                                                
if test; then echo "it is"; fi                                 

产生:

it is                                                                           

因为隐式返回了0(即true)。

现在,这就是把我搞砸了...

test(){ true; }                                                
if [ test ]; then echo "it is"; fi                             

产生:

it is                                                                           

AND

test(){ false; }                                                
if [ test ]; then echo "it is"; fi                             

ALSO产生:

it is                                                                           

使用此处的括号会产生误报! (我推断“外部”命令的结果为0。)

我文章的主要收获是:不要像使用典型的相等性检查那样使用方括号来评估布尔函数(或变量)。 if [ x -eq 1 ]; then...

答案 9 :(得分:0)

紧接着@Bruno Bronosky和@mrteatime,我建议您只将布尔返回值写为“ backwards”。这就是我的意思:

foo()
{
    if [ "$1" == "bar" ]; then
        true; return
    else
        false; return
    fi;
}

这消除了每个return语句的难看的两行要求。