似乎通过在 PS0 和 PS1 变量中执行代码(据我所知,它们在运行提示命令之前和之后进行评估)应该可以记录每个运行命令的时间并将其显示在提示中.类似的东西:
user@machine ~/tmp
$ sleep 1
user@machine ~/tmp 1.01s
$
但是,我很快就卡在了 PS0 的记录时间上,因为这样的东西不起作用:
PS0='$(START=$(date +%s.%N))'
据我了解,START
赋值发生在子 shell 中,因此在 shell 中是不可见的。你会如何处理这个问题?
最佳答案
我正在寻找一个不同问题的解决方案并遇到了这个问题,并认为这听起来很酷。使用@Scheff作为我为其他问题开发的解决方案的基础,我提出了一个更优雅、功能更全的解决方案。
首先,我创建了一些函数来读取/写入内存中的时间。写入共享内存文件夹会阻止磁盘访问,并且如果由于某种原因未清理文件,则不会在重启时持续存在
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)
}
bash_ 函数的输入是 bash PID
这些函数和以下函数被添加到 ~/.bashrc 文件中
ROOTPID=$BASHPID
bash_getstarttime $ROOTPID
这些创建初始时间值并将 bash PID 存储为可以传递给函数的不同变量。然后将函数添加到 PS0 和 PS1
PS0='$(bash_getstarttime $ROOTPID) etc..'
PS1='\[\033[36m\] Execution time $(bash_getstoptime $ROOTPID)s\n'
PS1="$PS1"'and your normal PS1 here'
现在它会在处理终端输入之前在PS0中生成时间,并在处理终端输入后在PS1中再次生成时间,然后计算差值并添加到PS1中。最后,这段代码会在终端退出时清除存储的时间:
function runonexit (){
rm /dev/shm/${USER}.bashtime.${ROOTPID}
}
trap runonexit EXIT
将它们放在一起,再加上一些正在测试的额外代码,它看起来像这样:
重要的部分是以毫秒为单位的执行时间,以及存储在共享内存中的所有事件终端 PID 的 user.bashtime 文件。 PID 也在终端输入后立即显示,因为我将它的显示添加到 PS0,您可以看到添加和删除的 bashtime 文件。
PS0='$(bash_getstarttime $ROOTPID) $ROOTPID experiments \[\033[00m\]\n'
关于bash - 使用 PS0 和 PS1 显示每个 bash 命令的执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43201274/