choosing between $0 and BASH_SOURCE

后端 未结 3 860
半阙折子戏
半阙折子戏 2020-12-07 08:13

How does one choose between \"$0\" and \"${BASH_SOURCE[0]}\"

This description from GNU didn\'t help me much.

    BASH_SOURC         


        
3条回答
  •  执念已碎
    2020-12-07 08:56

    Note: For a POSIX-compliant solution, see this answer.

    ${BASH_SOURCE[0]} (or, more simply, $BASH_SOURCE[1] ) contains the (potentially relative) path of the containing script in all invocation scenarios, notably also when the script is sourced, which is not true for $0.

    Furthermore, as Charles Duffy points out, $0 can be set to an arbitrary value by the caller.
    On the flip side, $BASH_SOURCE can be empty, if no named file is involved; e.g.:
    echo 'echo "[$BASH_SOURCE]"' | bash

    The following example illustrates this:

    Script foo:

    #!/bin/bash
    echo "[$0] vs. [${BASH_SOURCE[0]}]"
    

    $ bash ./foo
    [./foo] vs. [./foo]
    
    $ ./foo
    [./foo] vs. [./foo]
    
    $ . ./foo
    [bash] vs. [./foo]
    

    $0 is part of the POSIX shell specification, whereas BASH_SOURCE, as the name suggests, is Bash-specific.


    [1] Optional reading: ${BASH_SOURCE[0]} vs. $BASH_SOURCE:

    Bash allows you to reference element 0 of an array variable using scalar notation: instead of writing ${arr[0]}, you can write $arr; in other words: if you reference the variable as if it were a scalar, you get the element at index 0.

    Using this feature obscures the fact that $arr is an array, which is why popular shell-code linter shellcheck.net issues the following warning (as of this writing):

    SC2128: Expanding an array without an index only gives the first element.

    On a side note: While this warning is helpful, it could be more precise, because you won't necessarily get the first element: It is specifically the element at index 0 that is returned, so if the first element has a higher index - which is possible in Bash - you'll get the empty string; try 'a[1]='hi'; echo "$a"'.
    (By contrast, zsh, ever the renegade, indeed does return the first element, irrespective of its index).

    You may choose to eschew this feature due to its obscurity, but it works predictably and, pragmatically speaking, you'll rarely, if ever, need to access indices other than 0 of array variable ${BASH_SOURCE[@]}.

提交回复
热议问题