从shell脚本中的被调用函数返回值

Returning value from called function in a shell script

我想从shell脚本中调用的函数返回值。 也许我错过了语法。 我尝试使用全局变量。 但这也行不通。 代码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
lockdir="somedir"
test() {
    retval=""

    if mkdir"$lockdir"
        then    # Directory did not exist, but it was created successfully
            echo >&2"successfully acquired lock: $lockdir"
            retval="true"
        else
            echo >&2"cannot acquire lock, giving up on $lockdir"
            retval="false"
    fi
    return retval
}


retval=test()
if ["$retval" =="true" ]
    then
        echo"directory not created"
    else
        echo"directory already created"
fi


Bash函数不能像您希望的那样直接返回字符串。你可以做三件事:

  • 回音一个字符串
  • 返回退出状态,这是一个数字,而不是字符串
  • 分享变量
  • 对于其他一些shell也是如此。

    以下是如何执行以下每个选项:

    1.回音弦

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    lockdir="somedir"
    testlock(){
        retval=""
        if mkdir"$lockdir"
        then # Directory did not exist, but it was created successfully
             echo >&2"successfully acquired lock: $lockdir"
             retval="true"
        else
             echo >&2"cannot acquire lock, giving up on $lockdir"
             retval="false"
        fi
        echo"$retval"
    }

    retval=$( testlock )
    if ["$retval" =="true" ]
    then
         echo"directory not created"
    else
         echo"directory already created"
    fi

    2.退回退出状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    lockdir="somedir"
    testlock(){
        if mkdir"$lockdir"
        then # Directory did not exist, but was created successfully
             echo >&2"successfully acquired lock: $lockdir"
             retval=0
        else
             echo >&2"cannot acquire lock, giving up on $lockdir"
             retval=1
        fi
        return"$retval"
    }

    testlock
    retval=$?
    if ["$retval" == 0 ]
    then
         echo"directory not created"
    else
         echo"directory already created"
    fi

    3.分享变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    lockdir="somedir"
    retval=-1
    testlock(){
        if mkdir"$lockdir"
        then # Directory did not exist, but it was created successfully
             echo >&2"successfully acquired lock: $lockdir"
             retval=0
        else
             echo >&2"cannot acquire lock, giving up on $lockdir"
             retval=1
        fi
    }

    testlock
    if ["$retval" == 0 ]
    then
         echo"directory not created"
    else
         echo"directory already created"
    fi


    你的工作方式太难了。你的整个脚本应该是:

    1
    2
    3
    4
    5
    if mkdir"$lockdir" 2> /dev/null; then
      echo lock acquired
    else
      echo could not acquire lock >&2
    fi

    但即使这样也可能过于冗长。我会编码:

    1
    mkdir"$lockdir" || exit 1

    但产生的错误信息有点模糊。


    如果它只是一个真/假测试,请将函数return 0表示成功,将return 1表示失败。那么测试将是:

    1
    2
    3
    4
    5
    if function_name; then
      do something
    else
      error condition
    fi


    我认为对于失败(glenn jackman)而言,为succ / 1返回0,而olibre的清晰和解释性答案则表示这一切;只是提到一种"组合"方法,用于结果不是二进制的情况,你宁愿设置一个变量而不是"回显"一个结果(例如,如果你的函数也假设要回应一些东西,这种方法将会不行)。然后怎样呢? (下面是Bourne Shell)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # Syntax _w (wrapReturn)
    # arg1 : method to wrap
    # arg2 : variable to set
    _w(){
    eval $1
    read $2 <<EOF
    $?
    EOF
    eval $2=\$$2
    }

    就像在(是的,这个例子有点傻,它只是一个例子)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    getDay(){
      d=`date '+%d'`
      [ $d -gt 255 ] && echo"Oh no a return value is 0-255!" && BAIL=0 # this will of course never happen, it's just to clarify the nature of returns
      return $d
    }

    dayzToSalary(){
      daysLeft=0
      if [ $1 -lt 26 ]; then
          daysLeft=`expr 25 - $1`
      else
         lastDayInMonth=`date -d"`date +%Y%m01` +1 month -1 day" +%d`
         rest=`expr $lastDayInMonth - 25`
         daysLeft=`expr 25 + $rest`
      fi
      echo"Mate, it's another $daysLeft days.."
    }

    # main
    _w getDay DAY # call getDay, save the result in the DAY variable
    dayzToSalary $DAY