Como capturar a entrada da linha de comando no arquivo de log e executá-la ao mesmo tempo?

4

Digamos que eu emita alguns comandos na linha de comando:

#capture what follows
$ echo "foo"
foo

# don't capture
$ echo "bing"
bing

# capture again
$ echo "bar"
bar

Como posso registrar comandos seletivamente em um arquivo de log, o qual somente captura os comandos emitidos no cli? Ou seja efetivamente alcançando algo semelhante a .bash_history , mas apenas para certos comandos:

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

Observe que a saída para STDOUT de cada comando deve ser não registrada.
Analisei o redirecionamento de IO , mas não consegui descobrir uma solução funcional.

    
por jottr 21.11.2014 / 17:04

4 respostas

4

Se você definir uma função como

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

depois de cada comando que você deseja registrar, você pode executar loglast para registrar o comando anterior.

O arquivo de log usado é (em ordem): o primeiro argumento opcional para loglast , ou $logfile se nenhum argumento for dado, ou $HOME/command.log como último padrão.

O sed -s '/^[[:space:]]*// remove os espaços iniciais que fc adiciona.

    
por 21.11.2014 / 18:34
7

A abordagem mais simples é usar a funcionalidade já fornecida pelo bash. Especificamente, a variável 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. 

Então, você poderia fazer algo tão simples quanto

$ HISTCONTROL=ignorespace

Em seguida, todos os comandos que você inserir com um espaço à esquerda serão ignorados:

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

Como você pode ver acima, o comando que começou com um espaço foi ignorado.

Você também pode usar 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.

Se você definir HISTIGNORE para algo como #foo e, em seguida, acrescentar isso aos comandos que deseja ignorar, poderá obter o mesmo efeito:

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

Em ambos os casos, se você quiser salvá-lo em um arquivo, basta executar history > file . Como alternativa, defina o arquivo de histórico como file para a sessão:

$ 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
    
por 21.11.2014 / 18:53
1

Use o comando script :

script -f filename.log

Inicia uma nova sessão e registra todos os seus comandos. Quando você sai, o arquivo é fechado.

    
por 21.11.2014 / 17:30
0

Eu poderia pensar no comando script para registrar os comandos. Mas isso tem a desvantagem de registrar tudo o que você obteve na saída padrão também.

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

Agora, o que você fez em sua sessão está registrado no arquivo 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

EDITAR

No entanto, como você precisa registrar apenas os comandos em vez da saída dos comandos, é possível fazer algo como sugerido aqui .

  1. Se você não tiver screen , instale-o usando apt-get install screen .
  2. Agora, adicione o conteúdo abaixo ao arquivo ~/.screenrc (mesmo que o arquivo não existe você pode criá-lo).

    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. Agora, inicie sua sessão digitando o comando screen e execute o seu comandos como faria normalmente.

  4. Agora, você pode ver a lista dos comandos usados no screen verificando o arquivo ~/.bash_history.${WINDOW} , em que ${WINDOW} corresponde ao número da tela em que você executou seus comandos.
por 21.11.2014 / 17:22