shell 在bash中的每个发出的命令之前和之后打印纪元时间

31moq8wy  于 2023-06-24  发布在  Shell
关注(0)|答案(2)|浏览(103)

我正在尝试修改我的~/.bash_profile,以便Unix epoch时间在bash中执行每个命令之前和之后自动打印,如下所示:

[prompt]$ some-maybe-multiline-command
Started execution at: <epoch time>
...
<stuff printed out by some-maybe-multiline-command, if any>
...
Finished execution at: <epoch time>
[prompt]$

我如何才能做到这一点?理想情况下,我希望这样做的副作用最小(例如:如果可能的话,我不希望此更改影响太多日志);理想情况下,它应该只影响我在终端屏幕上看到的内容。
非常感谢!
我找到了this answer Unix StackExchange,并试图将其应用于我的情况;但到目前为止我还没有成功。
trap <command> DEBUG添加到~/.bash_profile中是目前为止我找到的最接近解决方案的方法。但是,我不确定如何使<command>知道它是在执行发出的命令之前还是之后执行的

5m1hhzi4

5m1hhzi41#

您可以使用Bash的PS0(需要bash 4.4+)和PROMPT_COMMAND
根据man bash

  • 快速命令

如果此变量已设置,并且是一个数组,则在发出每个主提示符之前,将每个set元素的值作为命令执行。如果设置了此值但未设置数组变量,则将其值用作要执行的命令。

  • PS0

在阅读命令之后和执行命令之前,交互式Shell将展开并显示此参数的值。
示例:

PS0='>>> $( date +%s )\n'
PROMPT_COMMAND='echo "<<< $( date +%s )"'
$ echo hello world; sleep 2
>>> 1686801897
hello world
<<< 1686801899
3duebb1j

3duebb1j2#

trap command DEBUG在执行之前执行命令。所以你需要别的东西。
一种解决方案可以是PS1和陷阱的组合

function showBefore(){
    printf "started at %s\n" $(date +"%s")
}
trap showBefore DEBUG
export PS1="Ended at \D{%s}> "

示例输出

Ended at 1686798230> sleep 10
started at 1686798232
Ended at 1686798242>

您也可以使用PROMPT_COMMAND='printf "Ended at %s\n" $(date +"%s")'来代替PS1。这两种情况都发生在显示提示时,即上一个命令刚刚完成之后。但是随后(如您看到的链接所示)showBefore函数变得更加复杂,因为PROMPT_COMMAND的执行也将触发TRAP。这是不美观的(tho你可以忽略所有的“开始于行”,但第一)

相关问题