Equivalent of __FILE__ and __LINE__ in Bash

后端 未结 4 770

Is there any variable in bash that contains the name of the .sh file executed? The line number would be great too.

I want to use it in error messages such as:

<
相关标签:
4条回答
  • 2020-12-24 05:55

    I find the "BASH_SOURCE" and "BASH_LINENO" built-in arrays very useful:

    $ cat xx
    #!/bin/bash
    
    _ERR_HDR_FMT="%.23s %s[%s]: "
    _ERR_MSG_FMT="${_ERR_HDR_FMT}%s\n"
    
    error_msg() {
      printf "$_ERR_MSG_FMT" $(date +%F.%T.%N) ${BASH_SOURCE[1]##*/} ${BASH_LINENO[0]} "${@}"
    }
    
    error_msg "here"
    
    
    error_msg "and here"
    

    Invoking xx yields

    2010-06-16.15:33:13.069 xx[11]: here
    2010-06-16.15:33:13.073 xx[14]: and here
    
    0 讨论(0)
  • 2020-12-24 05:58

    You just need to

    echo $LINENO
    echo $(basename $0)
    
    0 讨论(0)
  • 2020-12-24 06:03
    #!/bin/bash
    
    echo $LINENO
    echo `basename $0`
    

    $LINENO for the current line number $0 for the current file. I used basename to ensure you only get the file name and not the path.

    UPDATE:

    #!/bin/bash
    
    MY_NAME=`basename $0`
    
    function ouch {
       echo "Fail @ [${MY_NAME}:${1}]"
       exit 1
    }
    
    ouch $LINENO
    

    You have to pass the line as a parameter if you use the function approach else you will get the line of the function definition.

    0 讨论(0)
  • 2020-12-24 06:03

    Here's how to do it in a reusable function. if the following is in a file named script:

    #!/bin/bash
    debug() {
      echo "${BASH_SOURCE[1]##*/}:${FUNCNAME[1]}[${BASH_LINENO[0]}]" > /dev/tty
    }
    debug
    

    This produces the output:

    script:main[5]    
    

    Which indicates the line on which debug was called.


    The following will print out the filename, function, line and an optional message.

    Also works in zsh for extra goodness.

    # Say the file, line number and optional message for debugging
    # Inspired by bash's `caller` builtin
    # Thanks to https://unix.stackexchange.com/a/453153/143394
    function yelp () {
      # shellcheck disable=SC2154  # undeclared zsh variables in bash
      if [[ $BASH_VERSION ]]; then
        local file=${BASH_SOURCE[1]##*/} func=${FUNCNAME[1]} line=${BASH_LINENO[0]}
      else  # zsh
        emulate -L zsh  # because we may be sourced by zsh `emulate bash -c`
        # $funcfiletrace has format:  file:line
        local file=${funcfiletrace[1]%:*} line=${funcfiletrace[1]##*:}
        local func=${funcstack[2]}
        [[ $func =~ / ]] && func=source  # $func may be filename. Use bash behaviour
      fi
      echo "${file##*/}:$func:$line $*" > /dev/tty
    }
    
    0 讨论(0)
提交回复
热议问题