Suponha que eu queira executar uma sequência de quatro comandos que eu executei antes. Se o primeiro for 432 no histórico de comandos, eu poderia fazer:
$ !432; !433; !434; !435
Estou curioso, existe uma maneira mais eficiente de conseguir isso?
Suponha que eu queira executar uma sequência de quatro comandos que eu executei antes. Se o primeiro for 432 no histórico de comandos, eu poderia fazer:
$ !432; !433; !434; !435
Estou curioso, existe uma maneira mais eficiente de conseguir isso?
Respostas:
Se se referir a comandos executados recentemente, uma maneira mais eficiente é referenciá-los com números negativos:
!-4; !-3; !-2; !-1
Além disso, depois de fazer isso, sua entrada no último histórico conterá toda a cadeia de comandos, para que você possa repeti-la !!
.
Edit:
Se você ainda não o conhece, 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, para fazer o mesmo que acima, usando
eval "`fc -ln -4 -1`"
Porém, isso tem uma ressalva: depois disso, a eval
linha é armazenada no histórico como o último comando. Então, se você executar isso novamente, você entrará em um loop!
Uma maneira mais segura de fazer isso é usar o fc
modo de operação padrão : encaminhar o intervalo de comandos selecionado para um editor e executá-los quando você sair dele. Experimentar:
fc -4 -1
Você pode até reverter a ordem do intervalo de comandos: fc -1 -4
Para visualizar um intervalo de comandos no histórico, use o fc
comando interno:
fc -ln 432 435
Para executá-los novamente:
eval "$(fc -ln 432 435)"
man fc
que não me dá nada. O que fc
significa? Que outras opções existem?
help fc
... e também help help
.... help: help [-dms] [pattern ...] Exibe informações sobre comandos internos.
-l
bandeira, ele será executado sem necessidade do mal eval
.
fc
significa "comando de localização" ou "comando de correção".
Existe uma maneira agradável e alternativa de executar vários comandos em sequência no histórico do Bash: em
vez de usar o substituto do histórico ( !432
ou !-4
), você pode pesquisar no histórico com Ctrl+ re depois de encontrar o primeiro comando que deseja execute, pressione Ctrl+ o( opere e opte pelo próximo ) em vez da returntecla
Isso iniciará o comando e proporá o próximo do histórico. Você pode acertar Ctrl+oquantas vezes quiser e terminar a sequência com returnuma última, ou Ctrl+cparar sem iniciá-la.
Ctrl-o
ele produz um literal ^o
e quebra meu (reverse-i-search)
. Talvez haja alguma outra configuração envolvida.
Para executar os comandos imediatamente, em vez de editá-los, eis uma versão sintaticamente mais fina da resposta do Giles usando 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 o fc deseja. Além disso, agora o histórico (recente) conterá os comandos reais do histórico, em vez da instrução eval.
fc
para loop e xsel
Isso funciona bem quando eu 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 possam precisar de alguma edição:
fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh
history -p \!43{2..5}
para imprimir os comandos 432 a 435 no terminal, adequado para copiar / colar subsequente.