为什么在 Mac 中加载 .bash_profile 返回错误代码 1

RNA*_*RNA 7 mac bash .bash-profile

每当我打开 bash 终端时,都会返回错误代码 1:

Last login: Tue Jan 15 16:19:53 on ttys000
spam@moss:~ $ echo $?
1
Run Code Online (Sandbox Code Playgroud)

我发现这是由我的最后一行代码引起的.bash_profile

test -f $HOME/.debug && export profile_bash_profile='.bash_profile' || return 0
Run Code Online (Sandbox Code Playgroud)

如果删除此行,则返回错误代码 0。我不明白这一行是如何引起任何问题的,因为我可以.bash_profile使用错误代码 0:

spam@moss:~ $ source .bash_profile
spam@moss:~ $ echo $?
0
Run Code Online (Sandbox Code Playgroud)

更新:

有谁知道 Mac 是如何加载 ~/.bash_profile 的?当登录外壳启动时,我怀疑 Mac 的来源。该return命令似乎没有按预期运行 - 当我将其return 5作为最后一行~/.bash_profile并启动登录 shell 时,它不会返回错误代码 5(我确定~/.bash_profile是加载的最后一个脚本)。

Dan*_*eck 5

请注意,在return没有sourced 脚本(例如returning from .bash_profile)的情况下在函数外部使用时会发生什么在man bash.

不同之处在于脚本或函数的返回代码如何在bash. 如果您return是一个值,则该值被分配调用代码的返回代码,例如您从中返回的函数调用或source命令。由于.bash_profile在 shell 初始化期间返回时没有这样的调用者,所以该值被简单地丢弃。您正在访问的$?前面语句返回代码

使用 Apple 的bash-86.1作为参考:

如果你source是一个脚本,它的内容会被解析和执行,直到return遇到一个语句。它的返回值是单独记录的,调用者 ( execute_command_internalin bash-3.2/execute_cmd.c) 负责将其值分配给保存最后一个退出代码的变量:last_command_exit_value

如果这就是所谓的启动脚本,它是通过调用加载maybe_execute_filerun_startup_files函数bash/shell.c。这不是常规的命令执行:虽然文件的内容被正确执行,包括 final return,但没有人关心你返回的实际值。它被简单地丢弃。

那么,你在这里看到什么行为?本质上与您return不带参数调用一样:就像return简单地返回它前面的命令的返回码,在您的情况下,它是失败的测试。

如何获得所需的行为?既然你不能exit.bash_profile没有退出Shell,你需要确保命令紧接它产生所需的返回码,在这种情况下:

test -f $HOME/.debug && export profile_bash_profile='.bash_profile' || { true; return; }
Run Code Online (Sandbox Code Playgroud)


ter*_*don 2

我通过反复试验得出了以下结论。也许 BASH 专家可以解释更多。

  1. .bashrc内容:

    test -f $HOME/existent_file || return 4
    
    Run Code Online (Sandbox Code Playgroud)

    打开新终端后:

    $ echo $?
    0
    
    Run Code Online (Sandbox Code Playgroud)
  2. .bashrc内容:

    test -f $HOME/non_existent_file || return 4
    
    Run Code Online (Sandbox Code Playgroud)

    打开新终端后:

    $ echo $?
    1
    
    Run Code Online (Sandbox Code Playgroud)
  3. .bashrc内容:

    function foo () { 
        return 4 
    }
    foo;
    
    Run Code Online (Sandbox Code Playgroud)

    打开新终端后:

    $ echo $?
    4
    
    Run Code Online (Sandbox Code Playgroud)
  4. .bashrc内容:

    return 4
    
    Run Code Online (Sandbox Code Playgroud)

    打开新终端后:

    $ echo $?
    0
    
    Run Code Online (Sandbox Code Playgroud)
  5. 与上面相同.bashrc

    $ source ~/.bashrc
    $ echo $?
    4
    
    Run Code Online (Sandbox Code Playgroud)
  6. 这些命令直接从终端运行:

    $ test -f $HOME/existent_file  || return 4
    $ echo $?
    0
    $ test -f $HOME/non_existent_file  || return 4
    bash: return: can only `return' from a function or sourced script
    $ echo $?
    1
    
    Run Code Online (Sandbox Code Playgroud)

因此,return仅适用于函数和源文件。我不知道如何读取用户的信息~/.bashrc,但显然它没有来源。