How can the last command's wall time be put in the Bash prompt?

后端 未结 14 2659
無奈伤痛
無奈伤痛 2020-12-04 05:16

Is there a way to embed the last command\'s elapsed wall time in a Bash prompt? I\'m hoping for something that would look like this:

[last: 0s][/my/dir]$ sl         


        
相关标签:
14条回答
  • 2020-12-04 05:54

    Will putting a \t in PS1 work for you?

    It does not give the elapsed time but it should be easy enough to subtract the times when necessary.

    $ export PS1='[\t] [\w]\$ '
    [14:22:30] [/bin]$ sleep 10
    [14:22:42] [/bin]$
    

    Following the OP's comment that he is already using \t. If you can use tcsh instead of bash, you can set the time variable.

    /bin 1 > set time = 0
    /bin 2 > sleep 10
    0.015u 0.046s 0:10.09 0.4%      0+0k 0+0io 2570pf+0w
    /bin 3 >
    

    You can change the format of the printing to be less ugly (se the tcsh man page).

    /bin 4 > set time = ( 0 "last: %E" )
    /bin 5 > sleep 10
    last: 0:10.09
    /bin 6 >
    

    I do not know of a similar facility in bash

    0 讨论(0)
  • 2020-12-04 05:56

    You could utilize this zsh-borrowed hook for bash: http://www.twistedmatrix.com/users/glyph/preexec.bash.txt

    Timing done with this hook (Mac OS X): Use Growl to monitor long-running shell commands

    0 讨论(0)
  • 2020-12-04 05:56

    If somone just wants to see the time of execution, add this line to bash_profile

    trap 'printf "t=%s\n" $(date +%T.%3N)' DEBUG
    
    0 讨论(0)
  • 2020-12-04 05:57

    This is minimal stand-alone code to achieve what you want:

    function timer_start {
      timer=${timer:-$SECONDS}
    }
    
    function timer_stop {
      timer_show=$(($SECONDS - $timer))
      unset timer
    }
    
    trap 'timer_start' DEBUG
    PROMPT_COMMAND=timer_stop
    
    PS1='[last: ${timer_show}s][\w]$ '
    
    0 讨论(0)
  • 2020-12-04 05:57

    Translated version for zsh.

    Append to your ~/.zshrc file

    function preexec() {
      timer=$(date +%s%3N)
    }
    
    function precmd() {
      if [ $timer ]; then
        local now=$(date +%s%3N)
        local d_ms=$(($now-$timer))
        local d_s=$((d_ms / 1000))
        local ms=$((d_ms % 1000))
        local s=$((d_s % 60))
        local m=$(((d_s / 60) % 60))
        local h=$((d_s / 3600))
        if ((h > 0)); then elapsed=${h}h${m}m
        elif ((m > 0)); then elapsed=${m}m${s}s
        elif ((s >= 10)); then elapsed=${s}.$((ms / 100))s
        elif ((s > 0)); then elapsed=${s}.$((ms / 10))s
        else elapsed=${ms}ms
        fi
    
        export RPROMPT="%F{cyan}${elapsed} %{$reset_color%}"
        unset timer
      fi
    }
    
    0 讨论(0)
  • 2020-12-04 05:57

    this is my version

    • use date to format time, only calc days
    • set terminal title
    • use \$ in PS1 for user $ + root #
    • show return code / exit code
    • use date -u to disable DST
    • use hidden names like _foo
    _x_dt_min=1 # minimum running time to show delta T
    function _x_before {
        _x_t1=${_x_t1:-$(date -u '+%s.%N')} # float seconds
    }
    function _x_after {
        _x_rc=$? # return code
        _x_dt=$(echo $(date -u '+%s.%N') $_x_t1 | awk '{printf "%f", $1 - $2}')
        unset _x_t1
        #_x_dt=$(echo $_x_dt | awk '{printf "%f", $1 + 86400 * 1001}') # test
        # only show dT for long-running commands
        # ${f%.*} = int(floor(f))
        (( ${_x_dt%.*} >= $_x_dt_min )) && {
            _x_dt_d=$((${_x_dt%.*} / 86400))
            _x_dt_s='' # init delta T string
            (( $_x_dt_d > 0 )) && \
                _x_dt_s="${_x_dt_s}${_x_dt_d} days + "
            # format time
            # %4N = four digits of nsec
            _x_dt_s="${_x_dt_s}$(date -u -d0+${_x_dt}sec '+%T.%4N')"
            PS1='rc = ${_x_rc}\ndT = ${_x_dt_s}\n\$ '
        } || {
            PS1='rc = ${_x_rc}\n\$ '
        }
        # set terminal title to terminal number
        printf "\033]0;%s\007" $(tty | sed 's|^/dev/\(pts/\)\?||')
    }
    trap '_x_before' DEBUG
    PROMPT_COMMAND='_x_after'
    PS1='\$ '
    

    sample output:

    $ sleep 0.5
    rc = 0
    $ sleep 1
    rc = 0
    dT = 00:00:01.0040
    $ sleep 1001d
    rc = 0
    dT = 1001 days + 00:00:00.0713
    $ false
    rc = 1
    $ 
    
    0 讨论(0)
提交回复
热议问题