如何将命令行输入捕获到日志文件中并同时执行?

如何将命令行输入捕获到日志文件中并同时执行?

假设我在命令行上发出一些命令:

#capture what follows
$ echo "foo"
foo

# don't capture
$ echo "bing"
bing

# capture again
$ echo "bar"
bar

如何记录命令有选择地到日志文件,其中仅有的捕获命令自己在cli上发布?即有效地实现类似于 的功能.bash_history,但仅适用于某些命令:

$ cat command.log
echo "foo"
echo "bar"

注意输出STDOUT每个命令的to应该不是被记录。
我看过IO重定向,但无法找到可行的解决方案。

答案1

最简单的方法是使用 bash 已经提供的功能。具体来说,HISTIGNORE变量:

   HISTCONTROL
          A  colon-separated  list  of values controlling how commands are
          saved on the history list.   If  the  list  of  values  includes
          ignorespace,  lines  which  begin with a space character are not
          saved in the history list. 

所以,你可以做一些简单的事情

$ HISTCONTROL=ignorespace

然后,您输入的带有前导空格的任何命令都将被忽略:

HISTCONTROL=ignorespace
$ history -c            ## clear previous history for this session
$ echo foo
foo
$   echo bar
bar
$ history 
1  echo foo
2  history 

正如您在上面看到的,以空格开头的命令被忽略。


您还可以使用HISTIGNORE

    HISTIGNORE
          A colon-separated list of patterns used to decide which  command
          lines  should  be  saved  on  the history list.  Each pattern is
          anchored at the beginning of the line and must  match  the  com‐
          plete  line  (no  implicit  `*'  is  appended).  Each pattern is
          tested against the line after the checks specified  by  HISTCON‐
          TROL  are  applied.   In  addition  to  the normal shell pattern
          matching characters, `&' matches the previous history line.  `&'
          may  be  escaped  using  a  backslash;  the backslash is removed
          before attempting a match.  The second and subsequent lines of a
          multi-line compound command are not tested, and are added to the
          history regardless of the value of HISTIGNORE.

如果您设置HISTIGNORE类似的值#foo,然后将其附加到您想要忽略的命令中,您可以获得相同的效果:

$ HISTIGNORE="*#foo"
$ history -c  
$ echo foo
foo
$ echo "bar" #foo
bar
$ history 
1  echo foo
2  history 

在这两种情况下,如果您想将其保存到文件中,只需运行history > file.或者,file将会话的历史记录文件设置为:

$ HISTFILE="/tmp/file"
$ HISTCONTROL=ignorespace
$ history -c
$ echo foo
foo
$   echo bar
bar
$ history -a   ## write the session's history to $HISTFILE
$ cat /tmp/file 
echo foo
history -a

答案2

如果你定义一个像这样的函数

loglast() {
    fc -ln -1 | sed 's/^[[:space:]]*//' >> "${1:-${logfile:-~/command.log}}"
}

然后,在您想要记录的每个命令之后,您可以运行loglast来记录上一个命令。

使用的日志文件是(按顺序):可选的第一个参数loglast,或者$logfile如果没有给出参数,或者$HOME/command.log作为最后一个默认值。

删除添加的sed -s '/^[[:space:]]*//前导空格fc

答案3

使用script命令:

script -f filename.log

它启动一个新会话并记录您的所有命令。当您退出时,文件被关闭。

答案4

我可以想到script记录命令的命令。但这也有一个缺点,即会将您在标准输出中获得的所有内容都记录下来。

script -a #Start your scripting session. 

Script started, file is typescript
echo "Hello"
Hello
echo "Another Hello"
Another Hello
#Press Ctrl - D to exit the scripting session. 

Script done, file is typescript

现在,您在会话中所做的任何操作都会记录在打字稿文件。

cat typescript
Script started on Fri 21 Nov 2014 10:12:56 AM CST
echo "Hello"
Hello
echo "Another Hello"
Another Hello

Script done on Fri 21 Nov 2014 10:13:08 AM CST

编辑

但是,由于您只需要记录命令而不是命令的输出,因此您可以按照建议执行某些操作这里

  1. 如果没有screen,请使用 进行安装apt-get install screen
  2. 现在,将以下内容添加到文件中~/.screenrc(即使该文件不存在,您也可以创建它)。

    screen -t "window 0" 0 bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    screen -t "window 1" 1 bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    screen -t "window 2" bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    bind c screen bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    bind ^C screen bash -ic 'HISTFILE=~/.bash_history.${WINDOW} bash'
    
  3. 现在,通过键入命令开始会话screen并像平常一样执行命令。

  4. 现在,您可以通过检查与执行命令的屏幕编号相对应的文件screen来查看您在其中使用的命令列表。~/.bash_history.${WINDOW}${WINDOW}

相关内容