bash:如何拦截每个命令

时间:2011-08-03 17:23:26

标签: bash

有没有办法拦截给bash的每个命令?我可以通过定义函数cd拦截特定命令,例如cd(),我也可以为其他命令一次一个命令地执行此操作。但是我可以编写一个在执行每个命令之前调用的函数吗?我想做一些命令簿记,然后执行命令。

MichałŠrajer的想法PS4='$(echo $(date) $(history 1) >> /tmp/trace.txt) TRACE: '看起来很有希望,但这是我得到的输出:

$ ping www.google.com
 TRACE: ping www.google.com
PING www.l.google.com (74.125.224.52) 56(84) bytes of data.
64 bytes from 74.125.224.52: icmp_seq=1 ttl=56 time=3.77 ms
64 bytes from 74.125.224.52: icmp_seq=2 ttl=56 time=2.33 ms
^C
--- www.l.google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 2.334/3.054/3.774/0.720 ms
  TRACE: echo -ne '\033]0;myhost.com /home/yogeshwer/github/myproject\007'
  TRACE: grep -e '\* '
  TRACE: git branch
  TRACE: sed 's/^..\(.*\)/ {\1}/'

Wed Aug 3 12:47:27 PDT 2011 6672 ping www.google.com恰好用/tmp/trace.txt写了5次。其他四个来自我对PS1的定义,其中我运行以下命令:$(git branch 2> /dev/null | grep -e "\* " | sed "s/^..\(.*\)/ {\1}/")。两个问题:

  • 是否可以准确地将命令写入/tmp/trace.txt
  • 更重要的是,是否可以不混淆命令的输出,而只是将命令写入/tmp/trace.txt

我很高兴能够在一个地方记录来自我所有bash会话的命令!

5 个答案:

答案 0 :(得分:8)

您可以设置PS4变量,如果跟踪打开,该变量将在执行之前执行的每个命令进行评估:

PS4='$(echo $(date) $(history 1) >> /tmp/trace.txt) TRACE: '

然后,启用跟踪:

set -x

要停止追踪,只需:

set +x

答案 1 :(得分:4)

$PROMPT_COMMAND,如果设置,则包含在打印提示符($PS1)之前执行的命令。将其设置为捕获history 1

输出的函数的名称

答案 2 :(得分:3)

如果有人通过Google发现此问题,我通过在~/.bashrc添加以下内容来解决此问题。

PROMPT_COMMAND='echo "$(date +"%Y/%m/%d (%H:%M)") $(history 1 |cut -c 7-)" >> /tmp/trace'
export PROMPT_COMMAND

这导致/ tmp / trace具有诸如

之类的内容
2015/01/21 (14:34) pwd
2015/01/21 (14:36) less /tmp/trace
2015/01/21 (14:36) cd Documents
2015/01/21 (14:36) cd ..
2015/01/21 (14:36) ls -la
2015/01/21 (14:36) pwd
2015/01/21 (14:36) echo "helloWorld"
    在通过bash 运行的每个命令之后执行
  • PROMPT_COMMAND
  • $(date +"%Y/%m/%d (%H:%M)")打印日期和时间
  • $(history 1 |cut -c 7-)打印命令
    • cut -c 7-删除history包含的数字
  • >> /tmp/trace将完整字符串附加到您指定的文件。 (我会反对/tmp/中的任何内容,除非您希望在重新启动计算机时将其删除。)

答案 3 :(得分:1)

不确定拦截每个命令,但在某些版本的Linux中,每个命令都会记录到〜/ .bash_history。您可以弄清楚它是如何工作的,或者只是解析该文件以查看最后一个命令。

答案 4 :(得分:1)

您可以使用陷阱与DEBUG执行此操作,例如trap 'a oneliner in here' DEBUG