Algumas Dicas de Bash
---------------------------------------------------------------------
Colaboração: Rodrigo Bernardo Pimentel <rbp@sp.conectiva.com.br>
O "history" (ou histórico) no bash, apesar de extremamente poderoso,
é muito pouco usado, além do tradicional "setinha pra cima" para exibir os
últimos comandos.
Seu comportamento é regido por algumas variáveis:
HISTSIZE
Tamanho (em número de comandos) do histórico.
HISTFILE
Arquivo em que serão salvos os comandos (normalmente ~/.bash_history).
HISTFILESIZE
Tamanho máximo (em linhas) do arquivo selecionado acima.
Se um valor for especificado, o arquivo será truncado para
conter apenas o número especificado de linhas.
Eu, por exemplo, uso HISTSIZE e HISTFILESIZE como 5000.
Outra variável interessante é
HISTCONTROL
Pode ter um dentre três valores: "ignorespace", "ignoredups"
ou "ignoreboth". Se se usar o primeiro, comandos começando com
espaço não vão para o histórico. Com o segundo (e isso é
particularmente interessante), se um comando é executado mais
de uma vez em seguida, só uma ocorrência vai para o
histórico. O terceiro implementa ambas as funcionalidades.
Finalmente, para quem costuma quebrar comandos em várias linhas
(quem sabe isso não vai em outra dica? ;) , pode ser interessante fazer
export command_oriented_history=1
(ou qualquer outro valor, basta a variável estar "setada") Isso faz
com que o bash tente salvar todas as linhas do comando, ao invés de salvar
cada linha como se fosse um comando diferente (o comportamento padrão).
O caracter associado ao histórico é '!' (exclamação). Aqui, é mais
fácil compreender com a ajuda de exemplos:
!bla - repete o último comando começando com "bla".
!?bla - repete o último comando contendo "bla".
!x - repete o comando de número "x" no histórico. Similarmente,
!-y - repete o "y-ésimo" comando, do atual pra trás.
!! - repete o último comando (ou seja, igual a !-1)
!# - repete tudo o que foi digitado na linha até aquele ponto. Por exemplo,
"ls !#" geraria "ls ls"
Depois de especificada a linha de que se quer tratar (com os
comandos anteriores), pode-se selecionar parte delas e modificá-la. Esse
tratamento das linhas é introduzido por ':' (dois pontos).
A seleção, em sua forma mais simples, é feito indicando-se um número
relativo à posição do argumento que você quer selecionar no comando (0 -
zero - é o comando em si). Assim, por exemplo
[rbp@muppets ~]$ ls bla
ls: bla: No such file or directory
[rbp@muppets ~]$ !!:0
ls
A linha "!!:0" pegou a última linha e executou só o "argumento zero"
(o comando em si). Poderíamos também fazer algo como:
[rbp@muppets ~]$ man xscreensaver
[rbp@muppets ~]$ !!:1
xscreensaver
Pode-se selecionar uma seqüência de argumentos, com "x-y" (do
argumento de número "x" ao de número "y", inclusive). Por exemplo,
[rbp@muppets ~]$ cat script1 script2 script3
(...)
[rbp@muppets ~]$ !!:1-2
script1 script2
(...)
[rbp@muppets ~]$
Complementando "^" é o argumento de número 1 (isto é, o primeiro
argumento depois do comando em si), "$" é o último. Podem-se fazer
abreviações como "x-" (igual a "x-$"), "-x" (igual a "1-x") ou "*" (igual a
"1-$").
Para se modificar o comando em questão (ou a porção selecionada
dele), o método mais comum é muito semelhante ao sed:
[rbp@muppets ~]$ mkdir diretorio1
[rbp@muppets ~]$ !!:s/1/2
mkdir diretorio2
O "s/1/2" substituiu "1" por "2" no comando anterior.
Juntando tudo:
[rbp@muppets ~]$ export EDITOR=emacs
[rbp@muppets ~]$ !!:1:s/EDITOR=//
emacs
Finalmente, uma dica: substituição do último comando executado pode
ser feita rapidamente com
^a^b - substitui "a" por "b" no último comando.
Mais dicas de bash
---------------------------------------------------------------------
Colaboração: Rodrigo Bernardo Pimentel [rbp@sp.conectiva.com.br]
Muitas vezes é necessário, em uma linha de comando, repetirem-se
palavras quase na íntegra, modificando-se somente um ou outro caracter. Por
exemplo:
# cp ~/.emacs ~/.emacs.bak
Ou, pior,
# cp /mnt/usr/share/emacs/20.7/etc/sex.6 /usr/share/emacs/20.7/etc/sex.6
(para alguém que tenha perdido o arquivo, por exemplo)
Bem, para os preguiçosos, mesmo o primeiro exemplo é demais.
Então, tentando minimizar ao máximo a quantidade de caracteres
digitados, podemos usar um pequeno truque de bash:
# cp ~/.emacs{,.bak}
O que isso faz? A palavra que contem as chaves é expandida em duas
palavras (neste caso, podem ser mais), separadas por espaço: a primeira
contém "~/.emacs" mais o que está entre chaves, antes da primeira vírgula
(nada); a segunda contém "~/.emacs" mais o que está depois da vírgula
(".bak"). O resultado final, expandido pelo bash, seria
# cp ~/.emacs ~/.emacs.bak
Outro exemplo seria:
# cat arq{1,2,3} > arq.final
Ou seja, o equivalente a
# cat arq1 arq2 arq3 > arq.final
Isso funciona também no meio de da palavra, ou mesmo no começo:
# cat /home/{rbp,queiroz,rms,torvalds}/.signature
# diff {/home/rbp/.,/etc/}bashrc
E, finalmente (e um pouco mais confuso), pode haver chaves dentro de
chaves:
# less /usr/doc/{emacs-20.7/{NEWS,README},ed-0.2/NEWS,gnupg-1.0.1/{README,COPYING}}
Que seria expandido para:
# less /usr/doc/emacs-20.7/NEWS /usr/doc/emacs-20.7/README /usr/doc/ed-0.2/NEWS /usr/doc/gnupg-1.0.1/README /usr/doc/gnupg-1.0.1/COPYING
______________________________________________________________________________
Rodrigo Bernardo Pimentel <rbp@sp.conectiva.com.br>| GPG KeyID: 0x81F85A48
LinuxSP <http://www.linuxsp.org.br>| Fingerprint:
AirGeeks <http://www.airgeeks.org>|7E62 9CA2 C95B FC86 B334
____________<http://www.conectiva.com.br>___________|203E C011 2E4D 81F8 5A48
Mirrors should reflect a little before throwing back images.
---------------------------------------------------------------
As mensagens da lista Dicas-L são veiculadas diariamente
para 8956 assinantes.
Para sair ou assinar a lista Dicas-L, consulte o documento que
se encontra em http://www.Dicas-L.unicamp.br/FAQ.html.
A redistribuição desta e outras mensagens da lista Dicas-L pode
ser feita livremente, deste que o conteúdo, inclusive esta nota,
não sejam modificados.