首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用PS0和PS1显示每个bash命令的执行时间

使用PS0和PS1显示每个bash命令的执行时间
EN

Stack Overflow用户
提问于 2017-04-04 07:48:56
回答 5查看 2.8K关注 0票数 9

似乎通过执行PS0和PS1变量中的代码(据我所知,它们是在运行提示命令之前和之后求值的),应该可以记录每个运行命令的时间并将其显示在提示符中。大概是这样的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
user@machine ~/tmp
$ sleep 1

user@machine ~/tmp 1.01s
$

然而,我很快就在PS0中遇到了录制时间的问题,因为这样的东西不能工作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PS0='$(START=$(date +%s.%N))'

据我所知,START赋值发生在子shell中,因此它在外壳中不可见。您将如何处理此问题?

EN

回答 5

Stack Overflow用户

发布于 2019-09-27 20:00:00

我正在寻找一个不同问题的解决方案,并遇到了这个问题,并决定拥有一个听起来很酷的功能。除了我为其他问题开发的解决方案之外,使用@Scheff的优秀答案作为基础,我想出了一个更优雅和功能齐全的解决方案。

首先,我创建了几个函数来读取/写入内存中的时间。写入共享内存文件夹会阻止磁盘访问,并且如果由于某种原因未清除文件,则在重新启动时也不会持续存在

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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文件中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ROOTPID=$BASHPID
bash_getstarttime $ROOTPID

它们创建初始时间值并将bash PID存储为可以传递给函数的不同变量。然后将函数添加到PS0和PS1中

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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中。最后,此代码在终端退出时清理存储的时间:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function runonexit (){
  rm /dev/shm/${USER}.bashtime.${ROOTPID}
}

trap runonexit EXIT

将所有这些放在一起,加上一些正在测试的额外代码,它看起来如下所示:

重要的部分是以毫秒为单位的执行时间,以及存储在共享存储器中的所有活动终端PID的user.bashtime文件。PID也显示在终端输入之后,正如我在PS0中添加的一样,您可以看到添加和删除的bashtime文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PS0='$(bash_getstarttime $ROOTPID) $ROOTPID experiments \[\033[00m\]\n'
票数 6
EN

Stack Overflow用户

发布于 2017-04-04 09:55:17

我把这个当作拼图,并想展示我的拼图的结果:

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ START=$(date +%s.%N)

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

$

这足以计算时间差。

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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

$

该死的!我又一次被困在了子shell问题中。为了解决这个问题,我定义了另一个变量:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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结合起来。在一个类似的拼图(SO: How to change bash prompt color based on exit code of last command?)中,我已经掌握了“引用地狱”这个词。因此,我应该能够再做一次:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ 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,它似乎是最适合这一点的,而且我过去已经在其他一些个人定制中使用过它。

所以,把所有这些放在一起-这些是我添加到我的~/.bashrc中的行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 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创建的cygwin xterm的快照,其中我将以上几行添加到了./~bashrc

备注:

  1. 我认为这与其说是一个难题的解决方案,不如说是一个“严肃的、富有成效的”解决方案。我敢肯定,这种时间测量本身就会消耗很多时间。time命令可能提供更好的解决方案:SE: How to get execution time of a script effectively?。然而,这是一个练习bash...
  2. Don't的很好的讲座,忘记这段代码会用越来越多的小文件污染你的/tmp目录。不时清理/tmp或添加适当的命令进行清理(例如,添加到~/.bash_logout).
票数 2
EN

Stack Overflow用户

发布于 2020-06-16 19:05:38

算术扩展在当前进程中运行,并可以赋值给变量。它还生成输出,您可以使用\e[$((...,0))m (输出\e[0m)或${t:0:$((...,0))} (不输出任何内容,这可能更好)来使用输出。Bash支持中的64位整数支持将把POSIX纳秒计算到2262年。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ PS0='${t:0:$((t=$(date +%s%N),0))}'
$ PS1='$((( t )) && printf %d.%09ds $((t=$(date +%s%N)-t,t/1000000000)) $((t%1000000000)))${t:0:$((t=0))}\n$ '
0.053282161s
$ sleep 1
1.064178281s
$ 

$ 

对于空命令,不会对PS0求值,这会留下一个空行(我不确定是否可以在不破坏内容的情况下有条件地打印\n )。你可以通过切换到PROMPT_COMMAND来解决这个问题(这也节省了一个分支):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ PS0='${t:0:$((t=$(date +%s%N),0))}'
$ PROMPT_COMMAND='(( t )) && printf %d.%09ds\\n $((t=$(date +%s%N)-t,t/1000000000)) $((t%1000000000)); t=0'
0.041584565s
$ sleep 1
1.077152833s
$ 
$ 

也就是说,如果您不需要亚秒级的精度,我建议使用$SECONDS (如果时间设置了时间,它也更有可能返回一个合理的答案)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43201274

复制
相关文章
php中的时间戳与javascript中的时间戳的比较
php中的时间戳与javascript中的时间戳的比较,本质上看,它们是一样的东西,但如果二者要进行相等比较的时候,还是有点不同的,稍不注意,就会误入歧途,所以,这里列出容易忽略的两点不同,供大家参考:
风柏杨4711
2021/03/15
3.4K0
Java中获取时间戳
** 最近项目开发过程中发现了项目中获取时间戳的业务。而获取时间戳有以下三种方式,首先先声明推荐使用System类来获取时间戳,下面一起看一看三种方式。
全栈程序员站长
2022/08/18
2.6K0
时间,时间戳
将如上的时间2016-05-05 20:28:54转换成时间戳,具体的操作过程为:
zhengzongwei
2019/07/31
5.1K0
时间戳 时间
背景 由于团队业务做的是国际项目,就无法避免一个问题--时区问题,很多业务都是跟时间有关。一些时间的对比,时间的展示,都会涉及到时区和时间戳,所以花点时间来简单总结一下 概念 时间戳 时间戳是一个自增的整数,它表示从1970年1月1日零时整的GMT时区开始的那一刻,到现在的毫秒数。假设浏览器所在电脑的时间是准确的,那么世界上无论哪个时区的电脑,它们此刻产生的时间戳数字都是一样的,所以,时间戳可以精确地表示一个时刻,并且与时区无关。 时区 时区(Time Zone)是地球上的区域使用同一个时间定义。188
千往
2018/01/24
5.8K0
ffmpeg中的时间戳与时间基
在开发多媒体播放器或直播系统时,音视频的同步是非常关键且复杂的点。要想把音视频同步搞明白,我们必须要了解一些基本的知识。只有了解了这些基本知识,才能为你打下理解音视频同步的基础。 本文将从下面几个主题介绍这些知识点:
音视频_李超
2020/04/02
3K0
ffmpeg中的时间戳与时间基
Python获取当前时间戳_时间转换时间戳
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/10
9.6K0
sql中时间戳转日期
需求: 我将博客和 typecho 后台结合起来,打算做一个在线说说的功能,在 typecho 中输入内容,然后调用接口,实现在我的博客查看说说功能的功能。是不是有点绕?我也这么觉得,但是折腾一下也挺好的。
子舒
2022/06/09
4.3K0
sql中时间戳转日期
python中时间、日期、时间戳的转换
1.简介 在编写代码时,往往涉及时间、日期、时间戳的相互转换。 2.示例 # 引入模块 import time, datetime 2.1 str类型的日期转换为时间戳 1 # 字符类型的时间 2 tss1 = '2013-10-10 23:40:00' 3 # 转为时间数组 4 timeArray = time.strptime(tss1, "%Y-%m-%d %H:%M:%S") 5 print timeArray 6 # timeArray可以调用tm_year等 7 prin
kirin
2020/05/16
3.8K0
Unix 时间戳;时间戳获取和生成
Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。
西湖醋鱼
2020/12/30
9.2K0
Linux时间戳转换_时间戳转换软件
在大多数 UNIX 系统中,当前时间存储为自特定时刻以来经过的时间以简化,将时间保持为长整数。所有 UNIX 系统普遍接受的时刻是 1970 年 1 月 1 日凌晨 12:00:00。 这称为 UNIX 时间戳,并被所有现代 UNIX/Linux 系统识别。
全栈程序员站长
2022/11/09
15.7K0
Linux时间戳转换_时间戳转换软件
Python获取时间戳_python爬虫时间戳
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/189145.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/27
5.9K0
[MySQL]更新时间(加上或者减去一段时间)
定义和用法 DATE_ADD() 函数向日期添加指定的时间间隔。 DATE_SUB() 函数向日期减少指定的时间间隔。 语法 DATE_ADD(date,INTERVAL expr type) DATE_SUB(date,INTERVAL expr type)
用户2353021
2020/05/11
3.9K0
[MySQL]更新时间(加上或者减去一段时间)
Java中时间戳的使用
当前时间 import java.sql.Timestamp; //导包 Timestamp nowTime = new Timestamp(System.currentTimeMillis()); System.out.println(nowTime); 输出: 2022-06-08 11:15:51.014 Long型时间戳 Long timeLong = System.currentTimeMillis(); System.out.println("timeString:" + timeLon
代码的路
2022/11/29
1.8K0
Linux时间戳转换_如何获取时间戳
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/09
13.2K0
Decision Trees in Apache Spark (Apache Spark中的决策树)
Decision Trees in Apache Spark 原文作者:Akash Sethi 原文地址:https://dzone.com/articles/decision-trees-in-apache-spark 译者微博:@从流域到海域 译者博客:blog.csdn.blog/solo95 本文同样刊载于腾讯云+:https://cloud.tencent.com/developer/article/1034616 ​ Apache Spark中的决策树 决策树是在顺序决策问题进行
Steve Wang
2018/02/05
1.1K0
Decision Trees in Apache Spark (Apache Spark中的决策树)
时间戳
时间戳是自 1970 年 1 月 1 日(00:00:00 GMT)以来的秒数。它也被称为 Unix 时间戳(Unix Timestamp)。
KEVINGUO_CN
2020/03/17
3.9K0
java 时间戳字符串_Java获取当前时间戳/时间戳转换
public classApp {public static voidmain(String[] args) {//精确到毫秒//获取当前时间戳
全栈程序员站长
2022/08/11
8.4K0
点击加载更多

相似问题

从时间戳减去天数

111

从时间戳python中减去天数

155

从时间戳列中减去

18

减去/在Pandas时间戳中添加天数

24

Excel从日期中删除时间戳并减去天数

31
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文