Como executar comandos consecutivos do histórico?

47

Suponha que eu queira executar uma seqüência de quatro comandos que eu executei antes. Se o primeiro é 432 no histórico de comandos, então eu poderia fazer:

$ !432; !433; !434; !435

Estou curioso, existe uma maneira mais eficiente de conseguir isso?

    
por Eric Wilson 16.11.2011 / 17:42

5 respostas

47

Se se referir a comandos executados apenas recentemente, uma maneira mais eficiente é referenciá-los com números negativos:

!-4; !-3; !-2; !-1

Além disso, quando você fizer isso, sua última entrada no histórico conterá toda a cadeia de comandos, para que você possa repeti-la com !! .

Editar: Se ainda não o fez, familiarize-se com a excelente função incorporada fc , mencionada por Gilles . (Use help fc .) Acontece que você também pode usar números negativos com ele, então você pode fazer o mesmo que acima usando

eval "'fc -ln -4 -1'"

Isso tem uma ressalva: depois disso, a linha eval é armazenada no histórico como o último comando. Então, se você executar isso de novo, você vai cair em um loop!

Uma maneira mais segura de fazer isso é usar o modo de operação fc padrão: encaminhando o intervalo de comandos selecionado para um editor e executando-os assim que você sair dele. Experimente:

 fc -4 -1

Você pode até inverter a ordem do intervalo de comandos: fc -1 -4

    
por 16.11.2011 / 17:53
31

Para visualizar um intervalo de comandos no histórico, use o fc :

fc -ln 432 435

Para executá-los novamente:

eval "$(fc -ln 432 435)"
    
por 17.11.2011 / 00:12
9

Existe uma maneira agradável e alternativa de executar vários comandos em sequência a partir do histórico de Bash:
em vez de usar o history substitute ( !432 ou !-4 ), você pode pesquisar através do histórico com Ctrl + r , e depois de encontrar o primeiro comando deseja executar, tecle Ctrl + o ( operar-e-get-próximo ) ao invés da tecla retornar
Isto irá lançar o comando e propor o próximo a partir do histórico. Você pode pressionar Ctrl + o quantas vezes quiser e terminar a sequência com retornar para o último, ou Ctrl + c para parar sem iniciá-lo.

    
por 30.09.2015 / 11:01
7

Para executar os comandos imediatamente, em vez de editá-los, aqui está uma versão sintaticamente mais precisa de resposta do Giles usando o eval :

fc -e: 432 435

O argumento de dois pontos para -e é o bash noop, que tem o efeito de pular a etapa "abrir em um editor" que fc deseja. Além disso, agora o histórico (recente) conterá os comandos reais do histórico, em vez da instrução eval.

    
por 06.03.2018 / 23:58
0

fc para loop e xsel

Isso funciona bem quando quero concatenar e executar novamente os últimos n comandos várias vezes:

fcn() (
  from="${1:-2}"
  to="${2:-1}"
  if [ "$from" -ne "$to" ]; then
    for i in 'seq "$from" -1 "$(($to + 1))"'; do
      printf "$(fc -ln -${i} -${i}) && "
    done
  fi
  printf "$(fc -ln -${to} -${to})"
)

Então:

$ echo a
a
$ echo b
b
$ echo c
c
$ fcn 3 1 | xsel -b
$ # Paste.
$  echo a &&  echo b &&  echo c
a
b
c
$ # Paste again if you feel like it.
$  echo a &&  echo b &&  echo c
a
b
c

Ou para comandos maiores que podem precisar de alguma edição:

fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh
    
por 11.03.2018 / 12:45