bash函数中return语句的行为

A B*_*A B 19 bash return function

我无法理解returnbash中内置的行为.这是一个示例脚本.

#!/bin/bash

dostuff() {
    date | while true; do
        echo returning 0
        return 0
        echo really-notreached
    done

    echo notreached
    return 3
}

dostuff
echo returncode: $?
Run Code Online (Sandbox Code Playgroud)

该脚本的输出是:

returning 0
notreached
returncode: 3
Run Code Online (Sandbox Code Playgroud)

但是,如果date |从第4行中删除,则输出符合我的预期:

returning 0
returncode: 0
Run Code Online (Sandbox Code Playgroud)

看起来return上面使用的语句就像我认为break语句应该表现的那样,但只有当循环位于管道的右侧时.为什么会这样?我无法在bash手册页或在线中找到任何解释此行为的内容.该脚本在bash 4.1.5和破折号0.5.5中的行为方式相同.

gle*_*man 21

在该date | while ...场景中,由于管道的存在,while循环在子shell中执行.因此,return语句打破循环,子shell结束,让你的函数继续.

您将不得不重新构建代码以删除管道,以便不创建子shell:

dostuff() {
    # redirect from a process substitution instead of a pipeline
    while true; do
        echo returning 0
        return 0
        echo really-notreached
    done < <(date)

    echo notreached
    return 3
}
Run Code Online (Sandbox Code Playgroud)


Der*_*ike 6

如果您return在函数内部,该函数将停止执行但整个程序不会退出。

如果你exit在一个函数里面,整个程序就会退出。

您不能return在 bash 脚本的主体中,只能return在函数或源脚本中。


例如:

#!/usr/bin/env bash

function doSomething {
    echo "a"
    return
    echo "b"  # this will not execute because it is after 'return'
}

function doSomethingElse {
    echo "d"
    exit 0
    echo "e"  # this will not execute because the program has exited
}

doSomething
echo "c"
doSomethingElse
echo "f"  # this will not execute because the program exited in 'doSomethingElse'
Run Code Online (Sandbox Code Playgroud)

运行上面的代码会输出:

a
c
d
Run Code Online (Sandbox Code Playgroud)