Use PS0 and PS1 to display execution time of each bash command

后端 未结 3 1667
盖世英雄少女心
盖世英雄少女心 2020-12-18 04:29

It seems that by executing code in PS0 and PS1 variables (which are eval\'ed before and after a prompt command is run, as I understand) it should be possible to record time

3条回答
  •  甜味超标
    2020-12-18 04:42

    I was looking for a solution to a different problem and came upon this question, and decided that sounds like a cool feature to have. Using @Scheff's excellent answer as a base in addition to the solutions I developed for my other problem, I came up with a more elegant and full featured solution.

    First, I created a few functions that read/write the time to/from memory. Writing to the shared memory folder prevents disk access and does not persist on reboot if the files are not cleaned for some reason

    function roundseconds (){
      # rounds a number to 3 decimal places
      echo m=$1";h=0.5;scale=4;t=1000;if(m<0) h=-0.5;a=m*t+h;scale=3;a/t;" | bc
    }
    
    function bash_getstarttime (){
      # places the epoch time in ns into shared memory
      date +%s.%N >"/dev/shm/${USER}.bashtime.${1}"
    }
    
    function bash_getstoptime (){
      # reads stored epoch time and subtracts from current
      local endtime=$(date +%s.%N)
      local starttime=$(cat /dev/shm/${USER}.bashtime.${1})
      roundseconds $(echo $(eval echo "$endtime - $starttime") | bc)
    }
    

    The input to the bash_ functions is the bash PID

    Those functions and the following are added to the ~/.bashrc file

    ROOTPID=$BASHPID
    bash_getstarttime $ROOTPID
    

    These create the initial time value and store the bash PID as a different variable that can be passed to a function. Then you add the functions to PS0 and PS1

    PS0='$(bash_getstarttime $ROOTPID) etc..'
    PS1='\[\033[36m\] Execution time $(bash_getstoptime $ROOTPID)s\n'
    PS1="$PS1"'and your normal PS1 here'
    

    Now it will generate the time in PS0 prior to processing terminal input, and generate the time again in PS1 after processing terminal input, then calculate the difference and add to PS1. And finally, this code cleans up the stored time when the terminal exits:

    function runonexit (){
      rm /dev/shm/${USER}.bashtime.${ROOTPID}
    }
    
    trap runonexit EXIT
    

    Putting it all together, plus some additional code being tested, and it looks like this:

    The important parts are the execution time in ms, and the user.bashtime files for all active terminal PIDs stored in shared memory. The PID is also shown right after the terminal input, as I added display of it to PS0, and you can see the bashtime files added and removed.

    PS0='$(bash_getstarttime $ROOTPID) $ROOTPID experiments \[\033[00m\]\n'
    

提交回复
热议问题