最后一个命令和执行时间

最后一个命令和执行时间

我想获取最后使用的命令及其执行时间。这将用作通知别名的一部分。

答案1

注意:我假设bash是外壳。

适应其他 shell 应该不难。

获取最后使用的命令很简单:它存储在 shell 中事件指示符 !!,也可以使用 shell 内置命令获得fcfc -s)或history(使用一些字符串操作:)history 1 | awk '{$1=""}1'

但是,除非采取某些操作,否则无法获取执行时间或运行时间命令已执行。一旦运行命令,就什么也做不了了——马儿已经跑了。

要获取执行时间,可以执行以下操作之一:

  1. 设置HISTTIMEFORMAT变量,这将使bash执行时间保存在历史记录中,然后使用文本处理从输出中提取时间history
  2. 使用包装器手动保存执行时间。

为了获取运行时间,也可以:

  1. 如果您HISTTIMEFORMAT在运行命令之前已经设置,您可以解析输出以history获取执行时间,然后计算运行时间。
  2. 使用包装器运行命令timetime some-command。如果你想离开,处理的输出time有点混乱命令的输出未受影响
  3. 使用包装器根据手动保存的执行时间计算运行时间。

HISTTIMEFORMAT套装

如果您设置了HISTTIMEFORMAT变量,则无需使用包装器。首先,在您的 中.bashrc,设置HISTTIMEFORMAT。您可以将其设置为任何内容,只要它不为空即可。如果您不希望命令history显示时间,可以将其设置为空格 ( HISTTIMEFORMAT=" ")。

.bashrc现在, Ubuntu默认有一个别名:

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

我们可以将其调整以适合我们的目的:

alert_post () 
{ 
    RET=$?;
    END=$(date '+%s');
    LAST_COMM="$(HISTTIMEFORMAT='%s '; history 1)";
    START=$(awk '{print $2}' <<<"$LAST_COMM");
    START_TIME=$(date -d"@$START" '+%T %D');
    COMM=$(awk '{print $3}' <<<"$LAST_COMM");
    notify-send --urgency=low -i "$([ $RET = 0 ] && echo terminal || echo error)" "$COMM started at $START_TIME finished in $((END - START)) seconds.";
    return $RET
}
alias a=alert_post

你可以这样使用它:

$ sleep 10; a

包装函数

使用函数或脚本来包装命令:

alert_wrapper () 
{ 
    START=$SECONDS;
    START_TIME=$(date '+%T %D');
    COMM="$1";
    "$@";
    RET=$?;
    END=$SECONDS;
    notify-send --urgency=low -i "$([ $RET = 0 ] && echo terminal || echo error)" "$COMM started at $START_TIME finished in $((END - START)) seconds."
    return $RET
}
alias a=alertwrapper

然后运行以下列命令为前缀的命令a

$ a sleep 10

笔记:

  1. 获取时间的方法有很多,包括执行时间和运行时时间。我使用了$SECONDS特殊变量和date命令。你也可以只使用命令date
  2. 我已经使用了notify-usd,它应该在标准 Ubuntu 上可用。您可以查看其他生成通知的方法。
  3. 我已将命令的退出状态保存$RET归还了它,所以您应该能够依赖退出代码:do-something; a || echo "Couldn't do something."或者如果退出状态为非零a do-something || echo "Couldn't do something."则会。echodo-something

答案2

最后一条命令会保存在历史记录中。Bash 有一个fc命令可让您访问该信息(来自man bash):

fc [-e ename] [-lnr] [first] [last]
fc -s [pat=rep] [cmd]

第一种形式从历史列表中选择从 first 到 last 的一系列命令,并显示或编辑并重新执行它们。First 和 last 可以指定为字符串(用于定位以该字符串开头的最后一个命令)或数字(历史列表中的索引,其中负数用作当前命令号的偏移量)。如果没有指定 last,则将其设置为当前命令以进行列出(因此“fc -l -10”会打印最后 10 条命令),否则设置为 first。如果没有指定 first,则将其设置为上一个命令以进行编辑,并设置为 -16 以进行列出。

-n 选项在列出时隐藏命令编号。-r 选项反转命令的顺序。如果指定了 -l 选项,命令将列在标准输出中。否则,将对包含这些命令的文件调用 ename 指定的编辑器。如果没有指定 ename,则使用 FCEDIT 变量的值,如果未设置 FCEDIT,则使用 E​​DITOR 的值。如果两个变量均未设置,则使用 vi。编辑完成后,将回显并执行编辑的命令。

在第二种形式中,在用 rep 替换每个 pat 实例后,都会重新执行命令。命令的解释与上面的第一个命令相同。与此一起使用的一个有用的别名是r="fc -s"'', so that typingr cc'' 运行最后一个以 r'' 开头的命令,cc'' and typing重新执行最后一个命令。

如果使用第一种形式,则返回值为 0,除非遇到无效选项或 first 或 last 指定超出范围的历史记录行。如果提供了 -e 选项,则返回值为最后执行的命令的值,或者如果命令的临时文件发生错误则返回失败。如果使用第二种形式,则返回状态是重新执行的命令的状态,除非 cmd 未指定有效的历史记录行,在这种情况下 fc 返回失败。

还有一个名为的命令history。手册对此进行了详细解释。我不太确定哪一个更适合您的需求。

此外,要获取时间,您可能需要研究设置 HISTTIMEFORMAT。但是,我不太确定如何访问进程所花费的时间。也许应该使用 TIMEFORMAT。否则,Unix 方法是使用命令运行命令time。这将生成进程在运行时使用的各种时间和资源的输出。

摘自手册(man time):

time 使用任何给定的参数 ARG 运行程序 COMMAND.... 当 COMMAND 完成时,time 将显示有关 COMMAND 使用的资源的信息(默认情况下在标准错误输出上)。如果 COMMAND 以非零状态退出,time 将显示警告消息和退出状态。

相关内容