Pergunta

Todos nós sabemos como usar <ctrl>-R para reverter a pesquisa no histórico, mas você sabia que pode usar <ctrl>-S para encaminhar a pesquisa se você definir stty stop ""?Além disso, você já tentou executar bind -p para ver todos os atalhos de teclado listados?Existem mais de 455 no Mac OS X por padrão.

Qual é o seu truque obscuro, atalho de teclado ou configuração de shopt favorito usando o bash?

Foi útil?

Solução 7

Ao executar comandos, às vezes quero executar um comando com os argumentos anteriores.Para fazer isso, você pode usar este atalho:

$ mkdir /tmp/new
$ cd !!:*

Ocasionalmente, em vez de usar find, quebrarei um loop de uma linha se precisar executar vários comandos em uma lista de arquivos.

for file in *.wav; do lame "$file" "$(basename "$file" .wav).mp3" ; done;

Configurar as opções de histórico da linha de comando em meu .bash_login (ou .bashrc) é realmente útil.A seguir está um conjunto de configurações que uso no meu Macbook Pro.

Definir o seguinte faz com que o bash apague comandos duplicados em seu histórico:

export HISTCONTROL="erasedups:ignoreboth"

Eu também aumentei bastante o tamanho do meu histórico.Por que não?Não parece desacelerar nada nos microprocessadores atuais.

export HISTFILESIZE=500000
export HISTSIZE=100000

Outra coisa que faço é ignorar alguns comandos do meu histórico.Não há necessidade de lembrar o comando de saída.

export HISTIGNORE="&:[ ]*:exit"

Você definitivamente deseja definir histappend.Caso contrário, o bash substituirá seu histórico quando você sair.

shopt -s histappend

Outra opção que uso é o cmdhist.Isso permite salvar comandos multilinhas no histórico como um comando.

shopt -s cmdhist

Finalmente, no Mac OS X (se você não estiver usando o modo vi), você desejará redefinir <CTRL>-S para parar a rolagem.Isso evita que o bash seja capaz de interpretá-lo como pesquisa direta.

stty stop ""

Outras dicas

Renomear/mover arquivos com sufixos rapidamente:
cp /home/foo/realllylongname.cpp{,-old}

Isso se expande para:
cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old

cd -

É o equivalente em linha de comando do botão Voltar (leva você ao diretório anterior em que estava).

Outro favorito:

!!

Repete seu último comando.Mais útil no formato:

sudo !!

Meu favorito é '^string^string2' que pega o último comando, substitui string por string2 e o executa

$ ehco foo bar baz
bash: ehco: command not found
$ ^ehco^echo
foo bar baz

Guia do histórico da linha de comando Bash

renomear

Exemplo:

$ ls
this_has_text_to_find_1.txt
this_has_text_to_find_2.txt
this_has_text_to_find_3.txt
this_has_text_to_find_4.txt

$ rename 's/text_to_find/been_renamed/' *.txt
$ ls
this_has_been_renamed_1.txt
this_has_been_renamed_2.txt
this_has_been_renamed_3.txt
this_has_been_renamed_4.txt

Tão útil

sou fã do !$, !^ e !* expandos, retornando, da linha de comando enviada mais recentemente:o último item, o primeiro item sem comando e todos os itens sem comando.A saber (observe que o shell imprime o comando primeiro):

$ echo foo bar baz
foo bar baz
$ echo bang-dollar: !$ bang-hat: !^ bang-star: !*
echo bang-dollar: baz bang-hat: foo bang-star: foo bar baz
bang-dollar: baz bang-hat: foo bang-star: foo bar baz

Isso é útil quando você, digamos ls filea fileb, e deseja editar um deles: vi !$ ou ambos: vimdiff !*.Também pode ser generalizado para “o no argumento" assim:

$ echo foo bar baz
$ echo !:2
echo bar
bar

Finalmente, com nomes de caminhos, você pode obter partes do caminho anexando :h e :t para qualquer um dos expandos acima:

$ ls /usr/bin/id
/usr/bin/id
$ echo Head: !$:h  Tail: !$:t
echo Head: /usr/bin Tail: id
Head: /usr/bin Tail: id

Como listar apenas subdiretórios no atual?

ls -d */

É um truque simples, mas você não saberia quanto tempo eu precisei para encontrá-lo!

ESC.

Insere os últimos argumentos do seu último comando bash.É mais útil do que você pensa.

cp file /to/some/long/path

cd ESC.

Certamente você pode "diff file1.txt file2.txt", mas o Bash suporta substituição de processo, o que permite que você diff a saída de comandos.

Por exemplo, digamos que eu queira ter certeza de que meu script me dará o resultado esperado.Posso simplesmente agrupar meu script em <( ) e alimentá-lo diff para obter um teste de unidade rápido e sujo:

$ cat myscript.sh
#!/bin/sh
echo -e "one\nthree"
$
$ ./myscript.sh 
one
three
$
$ cat expected_output.txt
one
two
three
$
$ diff <(./myscript.sh) expected_output.txt
1a2
> two
$

Como outro exemplo, digamos que eu queira verificar se dois servidores possuem a mesma lista de RPMs instalados.Em vez de enviar sshing para cada servidor, gravar cada lista de RPMs em arquivos separados e fazer um diff nesses arquivos, posso simplesmente fazer o diff da minha estação de trabalho:

$ diff <(ssh server1 'rpm -qa | sort') <(ssh server2 'rpm -qa | sort')
241c240
< kernel-2.6.18-92.1.6.el5
---
> kernel-2.6.18-92.el5
317d315
< libsmi-0.4.5-2.el5
727,728d724
< wireshark-0.99.7-1.el5
< wireshark-gnome-0.99.7-1.el5
$

Existem mais exemplos no guia avançado de scripts em http://tldp.org/LDP/abs/html/process-sub.html.

Meu comando favorito é "ls -thor"

Ele convoca o poder dos deuses para listar os arquivos modificados mais recentemente em um formato convenientemente legível.

É mais uma novidade, mas é inteligente...

Os 10 principais comandos usados:

$ history | awk '{print $2}' | awk 'BEGIN {FS="|"}{print $1}' | sort | uniq -c | sort -nr | head

Exemplo de saída:

 242 git
  83 rake
  43 cd
  33 ss
  24 ls
  15 rsg
  11 cap
  10 dig
   9 ping
   3 vi

^R pesquisa reversa.Pressione ^R, digite um fragmento de um comando anterior que deseja corresponder e pressione ^R até encontrar o que deseja.Assim não preciso me lembrar de comandos usados ​​recentemente que ainda estão em meu histórico.Não exclusivamente bash, mas também:^E para final de linha, ^A para início de linha, ^U e ^K para excluir antes e depois do cursor, respectivamente.

Muitas vezes tenho aliases para vi, ls, etc.mas às vezes você quer escapar do alias.Basta adicionar uma barra invertida ao comando na frente:

Por exemplo:

$ alias vi=vim
$ # To escape the alias for vi:
$ \vi # This doesn't open VIM

Legal, não é?

Aqui estão alguns ajustes de configuração:

~/.inputrc:

"\C-[[A": history-search-backward
"\C-[[B": history-search-forward

Isso funciona da mesma forma que ^R mas usando as teclas de seta.Isso significa que posso digitar (por exemplo) cd /media/ então aperte a seta para cima para ir para a última coisa que eu cdgostaria de entrar no /media/ pasta.

(Eu uso o Gnome Terminal, talvez seja necessário alterar os códigos de escape para outros emuladores de terminal.)

A conclusão do Bash também é incrivelmente útil, mas é uma adição muito mais sutil.Em ~/.bashrc:

if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

Isso permitirá o preenchimento de guias por programa (por exemplo,tentando completar a tabulação quando a linha de comando começa com evince mostrará apenas os arquivos que o evince pode abrir e também completará as opções de linha de comando).

Funciona bem com isso também em ~/.inputrc:

set completion-ignore-case on
set show-all-if-ambiguous on
set show-all-if-unmodified on

Eu uso muito o seguinte:

O :p modificador para imprimir um resultado histórico.Por exemplo.

!!:p

Irá imprimir o último comando para que você possa verificar se está correto antes de executá-lo novamente.Basta entrar !! para executá-lo.

Na mesma linha:

!?foo?:p

Irá pesquisar em seu histórico o comando mais recente que continha a string 'foo' e imprimi-lo.

Se você não precisa imprimir,

!?foo

faz a pesquisa e a executa imediatamente.

Eu tenho uma arma secreta: concha-fu.

São milhares de dicas inteligentes, truques legais e receitas eficientes que na maioria das vezes cabem em uma única linha.

Um que eu adoro (mas trapaceio um pouco porque uso o fato de que o Python está instalado na maioria dos sistemas Unix agora):

alias webshare='python -m SimpleHTTPServer'

Agora toda vez que você digitar “webshare”, o diretório atual estará disponível através da porta 8000.Muito bom quando você deseja compartilhar arquivos com amigos em uma rede local sem chave USB ou diretório remoto.Streaming de vídeo e música também funcionará.

E, claro, a clássica bomba fork que é completamente inútil, mas ainda assim muito divertida:

$ :(){ :|:& };:

Não tente isso em um servidor de produção ...

Você pode usar o comando watch em conjunto com outro comando para procurar alterações.Um exemplo disso foi quando eu estava testando meu roteador e queria obter números atualizados sobre coisas como relação sinal-ruído, etc.

watch --interval=10 lynx -dump http://dslrouter/stats.html
type -a PROG

Para encontrar todos os lugares onde o Prog está disponível, geralmente em algum lugar em ~/bin, em vez de um em/usr/bin/prog que poderia ser esperado.

Eu gosto de construir comandos com eco e canalize-os para a casca:

$ find dir -name \*~ | xargs echo rm
...
$ find dir -name \*~ | xargs echo rm | ksh -s

Por que?Porque me permite ver o que vai ser feito antes de fazê-lo.Dessa forma, se eu tiver um erro horrível (como remover meu diretório inicial), posso detectá-lo antes que aconteça.Obviamente, isto é mais importante para ações destrutivas ou irrevogáveis.

Ao baixar um arquivo grande, costumo fazer:

while ls -la <filename>; do sleep 5; done

E então apenas ctrl+c quando terminar (ou se ls retorna diferente de zero).É semelhante ao watch programa, mas ele usa o shell, então funciona em plataformas sem watch.

Outra ferramenta útil é o netcat, ou nc.Se você fizer:

nc -l -p 9100 > printjob.prn

Então você pode configurar uma impressora em outro computador, mas em vez disso usar o endereço IP do computador que executa o netcat.Quando o trabalho de impressão é enviado, ele é recebido pelo computador que executa o netcat e despejado no printjob.prn.

pushd e popd quase sempre é útil

Uma maneira preferida de navegar quando estou usando vários diretórios em locais amplamente separados em uma hierarquia de árvore é usar acf_func.sh (listado abaixo).Uma vez definido, você pode fazer

cd --

para ver uma lista de diretórios recentes, com um menu numérico

disco-2

para ir para o segundo diretório mais recente.

Muito fácil de usar, muito prático.

Aqui está o código:

# do ". acd_func.sh"
# acd_func 1.0.5, 10-nov-2004
# petar marinov, http:/geocities.com/h2428, this is public domain

cd_func ()
{
  local x2 the_new_dir adir index
  local -i cnt

  if [[ $1 ==  "--" ]]; then
    dirs -v
    return 0
  fi

  the_new_dir=$1
  [[ -z $1 ]] && the_new_dir=$HOME

  if [[ ${the_new_dir:0:1} == '-' ]]; then
    #
    # Extract dir N from dirs
    index=${the_new_dir:1}
    [[ -z $index ]] && index=1
    adir=$(dirs +$index)
    [[ -z $adir ]] && return 1
    the_new_dir=$adir
  fi

  #
  # '~' has to be substituted by ${HOME}
  [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"

  #
  # Now change to the new dir and add to the top of the stack
  pushd "${the_new_dir}" > /dev/null
  [[ $? -ne 0 ]] && return 1
  the_new_dir=$(pwd)

  #
  # Trim down everything beyond 11th entry
  popd -n +11 2>/dev/null 1>/dev/null

  #
  # Remove any other occurence of this dir, skipping the top of the stack
  for ((cnt=1; cnt <= 10; cnt++)); do
    x2=$(dirs +${cnt} 2>/dev/null)
    [[ $? -ne 0 ]] && return 0
    [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
    if [[ "${x2}" == "${the_new_dir}" ]]; then
      popd -n +$cnt 2>/dev/null 1>/dev/null
      cnt=cnt-1
    fi
  done

  return 0
}

alias cd=cd_func

if [[ $BASH_VERSION > "2.05a" ]]; then
  # ctrl+w shows the menu
  bind -x "\"\C-w\":cd_func -- ;"
fi

Expanda linhas complicadas antes de acertar o temido enter

  • Alt.+Ctrl+elinha de expansão de shell (pode ser necessário usar Esc, Ctrl+e no seu teclado)
  • Ctrl+_desfazer
  • Ctrl+x, *glob-expandir-palavra

$ echo !$ !-2^ * Alt.+Ctrl+e
$ echo aword someotherword * Ctrl+_
$ echo !$ !-2^ * Ctrl+x, *
$ echo !$ !-2^ LOG Makefile bar.c foo.h

etc.

Sempre fui parcial em:

ctrl-E # move cursor to end of line
ctrl-A # move cursor to beginning of line

Eu também uso shopt -s cdable_vars, então você pode criar variáveis ​​bash para diretórios comuns.Então, para a árvore de origem da minha empresa, crio um monte de variáveis ​​como:

export Dcentmain="/var/localdata/p4ws/centaur/main/apps/core"

então posso mudar para esse diretório cd Dcentmain.

pbcopy

Isso copia para a área de transferência do sistema Mac.Você pode canalizar comandos para ele... tente:

pwd | pbcopy

$ touch {1,2}.txt
$ ls [12].txt
1.txt  2.txt
$ rm !:1
rm [12].txt
$ history | tail -10
...
10007  touch {1,2}.txt
...
$ !10007
touch {1,2}.txt
$ for f in *.txt; do mv $f ${f/txt/doc}; done

Usar 'set -o vi' na linha de comando, ou melhor, em .bashrc, coloca você no modo de edição vi na linha de comando.Você começa no modo 'inserir' para poder digitar e retroceder normalmente, mas se cometer um erro 'grande', pode pressionar a tecla esc e usar 'b' e 'f' para se mover como faz no vi.cw para alterar uma palavra.Particularmente útil depois de você abrir um comando de histórico que deseja alterar.

Semelhante a muitos acima, meu favorito atual é o pressionamento de tecla [alt].(teclas Alt e "." juntas) é o mesmo que $!(Insere o último argumento do comando anterior), exceto que é imediato e mais fácil de digitar.(Simplesmente não pode ser usado em scripts)

por exemplo:

mkdir -p /tmp/test/blah/oops/something
cd [alt].

Seque vários comandos juntos usando o && comando:

./run.sh && tail -f log.txt

ou

kill -9 1111 && ./start.sh
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top