对每个命令强制使用“添加”别名


11

是否可以向其中的每个命令强行添加定时别名(因为缺少更好的用短语表达的方式)bash

例如,我希望有一个特定的用户,每当运行命令时,该用户总是用date之前和之后或包裹time

这可能吗?如果可以,怎么办?


我看了看,却找不到确切的方法。正如Caleb所说的,您可以使用preexec,但是您不想在preexec(例如preexec() { time $1; })内部运行它,因为shell在preexec返回后仍会运行它。因此,我们能做的最好的事情就是类似的事情。
Mikel

@Mikel我认为您可以preexec()通过获取命令,从函数内部自己运行,然后返回某种错误,从而使外壳不再继续执行命令本身,来使用该函数实际包装正在执行的内容。
Caleb 2012年

Answers:


10

您可以记录命令行启动的时间和显示提示的时间。Bash已经在其历史记录中跟踪了每个命令行的开始日期,并且您可以记下显示下一个提示符的时间。

print_command_wall_clock_time () {
  echo Wall clock time: \
    $(($(date +%s) - $(HISTTIMEFORMAT="%s ";
                       set -o noglob;
                       set $(history 1); echo $2)))
}
PROMPT_COMMAND=print_command_wall_clock_time$'\n'"$PROMPT_COMMAND"

这只会为您提供第二个分辨率,而且只有墙上时钟时间。如果需要更好的分辨率,则需要使用date支持%N纳秒格式的外部命令,并在定时运行命令之前DEBUG调用陷阱date

call_date_before_command () {
  date_before=$(date +%s.%N)
}
print_wall_clock_time () {
  echo Wall clock time: \
    $((date +"$date_before - %s.%N" | bc))
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_command_wall_clock_time

即使使用了DEBUG陷阱,我也不认为有一种方法可以自动显示每个命令的处理器时间,或者比提示提示更具区分性。


如果您愿意使用其他Shell,请按照以下方法为zsh中的每个命令获取时间报告(这不会推广到其他任务):

REPORTTIME=0

您可以将其设置REPORTTIME为任何整数值,仅在处理器时间超过此秒数的命令中才会显示时序信息。

Zsh从名为的变量csh继承了此功能time


3

您在这里的选择将取决于您的外壳。其中zsh有一个方便的挂钩函数preexec(),它在任何交互式shell命令之前运行。通过使用该名称创建函数,可以使事情得以执行。您也可以通过调用函数跟进precmd()绘制下一提示之前将只运行,这将是右后你的命令完成。

通过创建这对函数,可以在提示符下发出任何命令之前和之后运行任何要运行的任意命令。您可以使用它来记录外壳使用情况,创建锁,测试环境,或者像您的示例中那样计算命令运行时所花费的时间或资源。

在此示例中,我们将在使用运行命令之前创建一个基准时间戳,然后使用preexec()计算出执行该命令所花费的时间precmd(),并在出现提示或将其注销之前将其输出。例:

preexec() {
   CMDSTART=$(date +%s%N)
}
precmd() {
   CMDRUNTIME=$(($(date +%s%N)-$CMDSTART))
   echo "Last command ran for $CMDRUNTIME nanoseconds."
}

注意:对于此特定示例,有一个更加简单的内置函数。您要做的就是在ZSH中打开运行时报告,它将自动执行此操作。

$ export REPORTTIME=0
$ ls -d
./
ls -BF --color=auto -d  0.00s user 0.00s system 0% cpu 0.002 total

在的更实际的实现中preexec(),我使用它查看外壳是否在内部运行,tmux或者screen,如果运行,则将有关当前正在运行的命令的信息发送到上游,以在选项卡名称中显示。

不幸的是,在bash中,这种小机制并不存在。这是一个人的尝试。另请参见Gilles对类似的小技巧的回答




希望这可以在bash中使用!
沃伦

参见Gilles的链接和其他链接,它可以在bash中实现,并且需要一点点摆弄。再次,为什么不只运行zsh?这是一个摇摆不定的外壳,除此以外,还有更多理由进行切换!
Caleb

2
如果您使用的是zsh,则还有更好的方法。设置了REPORTTIME环境变量后,对于任何耗时超过$ REPORTTIME秒的命令,将输出执行时间信息(就像您在命令前加上“ time”来运行该命令一样)。只需将其设置为0,它应该告诉您每个命令的时间,并引导用户/系统故障。
Joseph Garvin

1

最简单的方法可能是设置PROMPT_COMMAND。请参阅Bash变量

PROMPT_COMMAND(
如果设置),则将值解释为在打印每个主提示($PS1)之前要执行的命令。

例如,为避免覆盖任何现有的提示命令,可以执行以下操作:

PROMPT_COMMAND="date ; ${PROMPT_COMMAND}"

不知道那个-看起来像个不错的开始,@ cjm
沃伦

1
这只是一个开始,但没有解决知道何时运行命令的问题。在键入和运行命令之前,可能会在几分钟,几小时或几天内绘制提示本身。
Caleb

0

csh/ tcsh对此功能提供了最好的支持(并且一直都有)。

  The `time` shell variable can be set to execute the time builtin  command
  after the completion of any process that takes more than a given number
  of CPU seconds.

换句话说, set time=1将打印出占用cpu时间超过1秒的任何命令所消耗的时间(系统,用户,经过的时间)。Plain set time将启用打印所有命令的时间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.