使用PS0和PS1显示每个bash命令的执行时间 [英] Use PS0 and PS1 to display execution time of each bash command

查看:423
本文介绍了使用PS0和PS1显示每个bash命令的执行时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过执行PS0和PS1变量中的代码(据我所知,在运行提示命令之前和之后评估),应该可以记录每个正在运行的命令的时间并将其显示在提示中.像这样的东西:

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 of each running command and display it in the prompt. Something like that:

user@machine ~/tmp
$ sleep 1

user@machine ~/tmp 1.01s
$

但是,由于这样的事情不起作用,我很快就陷入了PS0中的录制时间:

However, I quickly got stuck with recording time in PS0, since something like this doesn't work:

PS0='$(START=$(date +%s.%N))'

据我了解,START分配发生在子外壳中,因此在外壳中不可见.您将如何处理?

As I understand, START assignment happens in a sub-shell, so it is not visible in the outer shell. How would you approach this?

推荐答案

我把这当作难题,并想显示我困惑的结果:

I took this as puzzle and want to show the result of my puzzling:

首先,我摆弄时间测量. date +%s.%N(我以前没有意识到)是我从那里开始的.不幸的是,似乎bash的算术评估似乎不支持浮点数.因此,我选择了其他东西:

First I fiddled with time measurement. The date +%s.%N (which I didn't realize before) was where I started from. Unfortunately, it seems that bashs arithmetic evaluation seems not to support floating points. Thus, I chosed something else:

$ START=$(date +%s.%N)

$ awk 'BEGIN { printf("%fs", '$(date +%s.%N)' - '$START') }' /dev/null
8.059526s

$

这足以计算时间差.

接下来,我确认了您已经描述的内容:子Shell调用阻止使用Shell变量.因此,我考虑了在哪里还可以存储开始时间,该时间对于子Shell来说是全局的,但是对于本地而言,足以在多个交互式Shell中同时使用.我的解决方案是临时的.文件(在/tmp中).为了提供唯一的名称,我想出了以下模式:/tmp/$USER.START.$BASHPID.

Next, I confirmed what you already described: sub-shell invocation prevents usage of shell variables. Thus, I thought about where else I could store the start time which is global for sub-shells but local enough to be used in multiple interactive shells concurrently. My solution are temp. files (in /tmp). To provide a unique name I came up with this pattern: /tmp/$USER.START.$BASHPID.

$ date +%s.%N >/tmp/$USER.START.$BASHPID ; \
> awk 'BEGIN { printf("%fs", '$(date +%s.%N)' - '$(cat /tmp/$USER.START.$BASHPID)') }' /dev/null
cat: /tmp/ds32737.START.11756: No such file or directory
awk: cmd. line:1: BEGIN { printf("%fs", 1491297723.111219300 - ) }
awk: cmd. line:1:                                              ^ syntax error

$

该死!再次,我陷入了子外壳问题.为了解决这个问题,我定义了另一个变量:

Damn! Again I'm trapped in the sub-shell issue. To come around this, I defined another variable:

$ INTERACTIVE_BASHPID=$BASHPID

$ date +%s.%N >/tmp/$USER.START.$INTERACTIVE_BASHPID ; \
> awk 'BEGIN { printf("%fs", '$(date +%s.%N)' - '$(cat /tmp/$USER.START.$INTERACTIVE_BASHPID)') }' /dev/null
0.075319s

$

下一步:将其与PS0PS1一起摆弄.在类似的难题中(

Next step: fiddle this together with PS0 and PS1. In a similar puzzle (SO: How to change bash prompt color based on exit code of last command?), I already mastered the "quoting hell". Thus, I should be able to do it again:

$ PS0='$(date +%s.%N >"/tmp/${USER}.START.${INTERACTIVE_BASHPID}")'

$ PS1='$(awk "BEGIN { printf(\"%fs\", "$(date +%s.%N)" - "$(cat /tmp/$USER.START.$INTERACTIVE_BASHPID)") }" /dev/null)'"$PS1"
0.118550s
$

啊.它开始工作.因此,只有一个问题-为INTERACTIVE_BASHPID的初始化找到正确的启动脚本.我发现~/.bashrc似乎是正确的选择,并且我过去已将其用于其他一些个人定制.

Ahh. It starts to work. Thus, there is only one issue - to find the right start-up script for the initialization of INTERACTIVE_BASHPID. I found ~/.bashrc which seems to be the right one for this, and which I already used in the past for some other personal customizations.

因此,将它们放在一起-这些是我添加到~/.bashrc的行:

So, putting it all together - these are the lines I added to my ~/.bashrc:

# command duration puzzle
INTERACTIVE_BASHPID=$BASHPID
date +%s.%N >"/tmp/${USER}.START.${INTERACTIVE_BASHPID}"
PS0='$(date +%s.%N >"/tmp/${USER}.START.${INTERACTIVE_BASHPID}")'
PS1='$(awk "BEGIN { printf(\"%fs\", "$(date +%s.%N)" - "$(cat /tmp/$USER.START.$INTERACTIVE_BASHPID)") }" /dev/null)'"$PS1"

已添加第三行(date命令)来解决另一个问题.将其注释掉并开始进行新的交互式bash找出原因.

The 3rd line (the date command) has been added to solve another issue. Comment it out and start a new interactive bash to find out why.

使用bash的cygwin xterm的快照,在其中我将以上几行添加到了./~bashrc:

A snapshot of my cygwin xterm with bash where I added the above lines to ./~bashrc:

注意:

  1. 我认为这是对难题的解决方案,而不是严重的生产性"解决方案.我敢肯定,这种时间测量会消耗很多时间. time命令可能提供更好的解决方案: SE :如何有效地获得脚本的执行时间?.但是,这是练习bash的不错的演讲...

  1. I consider this rather as solution to a puzzle than a "serious productive" solution. I'm sure that this kind of time measurement consumes itself a lot of time. The time command might provide a better solution: SE: How to get execution time of a script effectively?. However, this was a nice lecture for practicing the bash...

不要忘记此代码会污染越来越多的小文件,从而污染您的/tmp目录.

Don't forget that this code pollutes your /tmp directory with a growing number of small files. Either clean-up the /tmp from time to time or add the appropriate commands for clean-up (e.g. to ~/.bash_logout).

这篇关于使用PS0和PS1显示每个bash命令的执行时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆