quinta-feira, 21 de maio de 2015

10 Incríveis e Misteriosos Usos do Símbolo ou Operador (!) nos Comandos Linux

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256



Jaboatão dos Guararapes, PE, Brasil, 21 de maio de 2015.

Eis uma tradução livre do artigo divulgado por Avishek Kumar.
Disponível em:
<http://www.tecmint.com/mysterious-uses-of-symbol-or-operator-in-linux-commands/>.
Acesso em: 21 maio 2015.


10 Incríveis e Misteriosos Usos do Símbolo ou Operador (!) nos Comandos
Linux

   por Avishek Kumar
   Atualização mais recente: 18 maio 2015


   O símbolo ou operador "!" no Linux pode ser utilizado como operador
   Lógico de Negação bem como para recuperar comandos do histórico com
   truques ou para executar comandos previamente executados com
   modificação.   Todos os comandos abaixo foram verificados
   explicitamente no Shell bash.   Apesar de eu não ter verificado, mas
   a maior parte deles não funcionará em outro shell. Aqui vamos nós
   para os incríveis e misteriosos usos do símbolo ou operador "!" nos
   comandos Linux.
  

1. Execute um comando a partir do histórico pelo número do comando.

   Você pode não estar consciente do fato de que você pode executar um
   comando a partir do seu histórico de comandos (comandos já/antes
   executados).   Para começar, primeiro encontre o número do comando
   executando o comando "history".

$ history

   Agora execute um comando a partir do histórico simplesmente pelo
   número pelo qual o comando é listado, na saída do comando "history".  
   Digamos execute um comando que aparece no número 1551 na saída do
   comando "history".

$ !1551

   E, o comando é executado (o comando "top" no caso), o qual foi
   listado no número 1551.   Essa forma de recuperar um comando já
   executado é muito útil especialmente no caso daqueles comandos que
   são longos.   Você simplesmente precisa chamá-lo utilizando ![Número
   no qual o comando aparece na saída do comando "history"].



- ------------------------------
- ------------------------------


2. Execute um comando previamente executado como o 2º comando mais
recente, 7º comando mais recente, etc.

   Você pode executar aqueles comandos que você executou previamente
   pela sequência de execução deles, sendo que o comando executado mais
   recentemente será representado como -1; o segundo mais recente como
   -2; o sétimo mais recente como -7.
  
   Primeiro execute o comando "history" para obter uma lista dos
   comandos executados mais recentemente.   É obrigatório executar o
   comando "history", de forma que você pode ter certeza de que não
   existe um comando como o comando "rm arquivo" e outros simplesmente
   para ter certeza de que você não está executando qualquer comando
   perigoso acidentalmente.   E então verifique o Sexto comando mais
   recente, o Oitavo comando mais recente e o Décimo comando mais
   recente.

$ history
$ !-6
$ !-8
$ !-10


- ------------------------------
- ------------------------------


3. Passe argumentos do comando mais recente que nós executamos para o
novo comando sem redigitar

   Eu preciso listar o conteúdo do diretório
   "/home/$USER/Binary/firefox", então eu disparo.

$ ls /home/$USER/Binary/firefox

   Então eu percebo que eu deveria ter disparado "ls -l" para ver qual
   arquivo é executável?   Então eu deveria digitar o comando inteiro
   outra vez!   Não, eu não preciso.   Eu preciso simplesmente carregar
   o último argumento para este novo comando assim:

$ ls -l !$

   Aqui "!$" carregará argumentos passados no último comando para esse
   novo comando.


- ------------------------------
- ------------------------------


4. Como manipular dois ou mais argumentos utilizando (!)

   Digamos que eu criei um arquivo de texto chamado "1.txt" na Área de
   Trabalho.

$ touch /home/avi/Desktop/1.txt

   e então eu copio ele para "/home/avi/Downloads" utilizando o caminho
   completo em ambos os lados com o comando "cp".

$ cp /home/avi/Desktop/1.txt /home/avi/downloads

   Agora nós passamos dois argumentos com o comando "cp".   O primeiro
   argumento é "/home/avi/Desktop/1.txt" e o segundo é
   "/home/avi/downloads".   Vamos manipulá-los diferentemente,
   simplesmente execute "echo [argumentos]" para imprimir ambos os
   argumentos diferentemente.

$ echo “1st Argument is : !^”
$ echo “2nd Argument is : !cp:2”

   Perceba que o 1º argumento pode ser impresso como “!^” e o restante
   os argumentos podem ser impressos executando
   “![Name_of_Command]:[Number_of_argument]”.
  
   No exemplo acima, o primeiro comando foi "cp" e o 2º argumento foi
   necessário para se imprimir.   Dado “!cp:2”, se qualquer comando,
   digamos "xyz", for executado com 5 argumentos e você precisa do 4º
   argumento, você pode utilizar “!xyz:4”, e utilizá-lo como quiser.  
   Todos os argumentos podem ser acessados via “!*”.


- ------------------------------
- ------------------------------


5. Execute o comando mais recente na base de palavras-chave

   Nós podemos executar o comando mais recentemente executado na base de
   palavras-chave.   Podemos entender as palavras-chave conforme a
   seguir:

$ ls /home > /dev/null                                          [Command 1]
$ ls -l /home/avi/Desktop > /dev/null                           [Command 2]
$ ls -la /home/avi/Downloads > /dev/null                        [Command 3]
$ ls -lA /usr/bin > /dev/null                                   [Command 4]

   Aqui nós utilizamos o mesmo comando (ls), mas com diferentes
   modificadores e para diferentes diretórios.   Além disso, nós
   enviamos a saída de cada comando para "/dev/null", uma vez que não
   vamos lidar com a saída do comando, o que também mantém o console
   limpo.
  
   Agora, execute o comando mais recentemente executado na base de
   palavras-chave.

$ ! ls                                  [Command 1]
$ ! ls -l                               [Command 2]
$ ! ls -la                              [Command 3]
$ ! ls -lA                              [Command 4]

   Verifique a saída e você ficará atônito, pois você está executando
   comandos já executados simplesmente por palavras-chave do "ls".


- ------------------------------
- ------------------------------


6. O poder do Operador !!

   Você pode executar/alterar o seu comando mais recentemente executado
   utilizando (!!).   Isso chamará o comando mais recentemente executado
   com alterações/modificações no comando atual.   Vamos te mostrar o
   cenário.
  
   Ontem eu executei um script de uma linha para obter o meu número IP
   privado, então eu executei:

$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/

   Então, repentinamente, eu percebi que eu preciso redirecionar a saída
   do scrip acima para um arquivo ip.txt, então o que eu deveria fazer?  
   Eu deveria redigitar o comando inteiro novamente e redirecionar a
   saída para um arquivo?   Bem, uma solução simples é utilizar a tecla
   de navegação UP e adicionar "> ip.txt" para redirecionar a saída para
   um arquivo, como:

$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/ > ip.txt

   Agradeça à tecla de navegação UP salvadora de vida aqui.   Agora,
   considere a condição abaixo, a próxima vez que eu executar o scrip de
   uma linha abaixo.

$ ifconfig | grep "inet addr:" | awk '{print $2}' | grep -v '127.0.0.1' | cut -f2 -d:

   Tão logo eu execute o script, o prompt do bash retornou um erro com a
   mensagem:
  
   “bash: ifconfig: comando não encontrado”
  
   Não foi difícil para mim perceber que eu executei esse comando como
   um usuário comum, onde ele deveria ter sido executado como usuário
   root.
  
   Então, qual é a solução?   É difícil se logar como usuário "root" e
   então digitar o comando inteiro novamente!   Também (a Tecla de
   Navegação UP) no exemplo mais recente não veio salvar aqui.   Então?  
   Nós precisamos chamar “!!” sem as aspas, o qual chamará o comando
   mais recente para aquele usuário.

$ su -c “!!” root

   Aqui "su" é "switch user" - "permuta usuário" - o qual usuário é
   "root", "-c" é para executar o comando específico como o usuário e a
   parte mais importante "!!" será substituída por "comando" e o comando
   mais recentemente executado será substituído aqui.   Isso!   Você
   precisa fornecer a senha do usuário "root".
  
   Eu faço uso do "!!" a maioria nos cenários seguintes:

   1. Quando eu executo o comando "apt-get" como usuário normal, eu
   normalmente recebo um erro dizendo que você não tem permissão para
   executar.

$ apt-get upgrade && apt-get dist-upgrade

   Opa! não se preocupe! execute o comando abaixo para fazê-lo com
   sucesso:

$ su -c !!

   Da mesma maneira eu faço para:

$ service apache2 start

ou

$ /etc/init.d/apache2 start

ou

$ systemctl start apache2

   Oops! Usuário não autorizado a carregar tal tarefa, então eu executo:

$ su -c 'service apache2 start'

ou

$ su -c '/etc/init.d/apache2 start'

ou

$ su -c 'systemctl start apache2'


- ------------------------------
- ------------------------------


7. Execute um comando que afeta todos os arquivos, exceto
![NOME_ARQUIVO]

   O "!" (NÃO Lógico) pode ser utilizado para executar o comando sobre
   todos os arquivos/extensões, exceto aqueles atrás de "!".
  
   A. Remova todos os arquivos de um diretório, exceto aquele cujo nome
   é "2.txt".

$ rm !(2.txt)

   B. Remova todos os arquivos do tipo de um diretório, exceto aquele
   cuja extensão é "pdf".

$ $ rm !(*.pdf)


- ------------------------------
- ------------------------------


8. Verificar se um diretório (digamos "/home/avi/Tecmint") existe ou
não? Se o dito diretório existe ou não, imprima uma mensagem com o
comando "printf"

   Aqui nós utilizaremos "! -d" para validar se o diretório existe ou
   não, seguido pelo Operador Lógico AND (&&) para imprimir caso aquele
   diretório não exista; e o Operador Lógico OR (||) para imprimir caso
   o diretório esteja presente.
  
   A lógica é: quando a saída de [ ! -d /home/avi/Tecmint ] for 0
   (zero), será executado aquilo que pertence ao Operador Lógico AND; do
   contrário, a execução irá para o Operador Lógico OR (||) e executa
   aquilo que pertencer ao Operador Lógico OR.

$ [ ! -d /home/avi/Tecmint ] && printf '\nnão existe o tal diretório /home/avi/Tecmint\n' || printf '\nexiste o diretório /home/avi/Tecmint\n'


- ------------------------------
- ------------------------------


9. Verificar se um diretório existe ou não? Se não, sair do comando.

   Semelhante à condição acima, mas aqui se o diretório desejado não
   existir, a execução saíra do comando.

$ [ ! -d /home/avi/Tecmint ] && exit


- ------------------------------
- ------------------------------


10. Criar um diretório (digamos "teste") no seu diretório "home", caso
ele já não exista.

   Uma implementação geral em Linguagem de Script onde se o diretório
   desejado não existir, a execução criará um.

[ ! -d /home/avi/Tecmint ] && mkdir /home/avi/Tecmint


- ------------------------------
- ------------------------------


   Por enquanto é isso.   Se você souber ou descobrir qualquer outro
   uso de "!" o qual valha a pena saber, você pode desejar nos fornecer
   a sua sugestão em feedback.   Mantenha-se conectado!




    1. Edgar Allen says:
       May 19, 2015 at 10:30 pm
      
       Você também pode mencionar "!?"
      
       Isso encontra o comando mais recente com o argumento string dele.
       Por exemplo, se ...
      
       1013 grep tornado /usr/share/dict/words
       1014 grep hurricane /usr/share/dict/words
       1015 wc -l /usr/share/dict/words
      
       estão todos no histórico, então "!?torn" pesquisará por tornado
       novamente, onde "!torn" procuraria em vão por um comando iniciando
       com "torn".
      
       E "wc !?torn?:2" funciona para selecionar o argumento dois do
       comando contendo "tornado" e executar um "wc" sobre ele.

       Resposta:
          + Avishek Kumar says:
            May 20, 2015 at 11:25 am
           
            Caro Edgar,
            Sua sugestão foi levada em conta.
            Obrigado pelo seu feedback.
           
    2. Stephen says:
       May 19, 2015 at 6:07 pm
      
       Eu não vi uma menção do contexto histórico no artigo, então eu
       darei algum aqui nos comentários.   Essa forma de substituição
       de histórico de comando originou-se com o Shell C (csh), criado
       por Bill Joy para o sabor BSD de UNIX, lá no começo dos anos 70.
       Mais tarde foi incorporado no tcsh, e bash (Bourne-Again SHell).
       Pessoalmente, eu sempre tenho preferido o mecanismo de
       substituição de histórico do C-shell, e nunca realmente olhei
       para o comando "fc" (o qual eu encontrei primeiramente no Korne
       shell).
      
       Resposta:
          + Avishek Kumar says:
            May 20, 2015 at 11:27 am
           
            Caro Stephen,
            Obrigado pelo pedaço maravilhoso de informação.   Mantenha-se
            conectado e nos mantenha ciente de tal contexto.
           
    3. suzy says:
       May 16, 2015 at 11:45 am
      
       4º comando.   Você pode acessá-lo muito mais simplesmente.   Existem
       atualmente expressões regulares:
      
       ^ está no começo da expressão
       $ está no fim da expressão
       :number qualquer parâmetro de número

       Exemplo:
       touch a.txt b.txt c.txt
       echo !^ –> exibe o primeiro parâmetro
       echo !:1 –> também exibe o primeiro parâmetro
       echo !:2 –> exibe o segundo parâmetro
       echo !:3 –> exibe o terceiro parâmetro
       echo !$ –> exibe o último (no nosso caso, o 3º) parâmetro
       echo !* –> exibe todos os parâmetros
       Resposta:
          + Avishek Kumar says:
            May 18, 2015 at 11:30 pm
           
            E nós dissemos o mesmo:
            echo “1st Argument is : !^”
            $ echo “2nd Argument is : !cp:2”
           
            echo seguido do 1º argumento e 2º argumento é simplesmente tornar
            o tutorial e comando ininteligível.   Eu tenho utilizado "!^".
            "!command:number" como você está sugerindo.
            Eu gostaria de saber se você quer dizer algo diferente?

    4. Tomasz Wiszkowski says:
       May 16, 2015 at 10:50 am
      
       Eu penso (5) funciona diferentemente do que você anotou, e o
       redirecionamento para /dev/null escondeu, porém ZSh ainda
       imprime o comando.   Quando você invoca “! ls…”, sempre pega o
       comando "ls" mais recente que você executou, simplesmente acrescenta
       seus modificadores ao final (depois /dev/null).   Uma coisa extra legal
       é o operador "!#", o qual pega argumentos da linha atual.   Particularmente
       bom se você precisa redigitar nomes de caminho longos que você já digitou
       na linha atual.   Simplesmente digamos, por exemplo
      
       cp /some/long/path/to/file.abc !#:1

       E pressione "tab".   Isso vai substituir o último argumento com o nome do
       arquivo e caminho inteiro.

       Resposta:
          + Avishek Kumar says:
            May 18, 2015 at 11:37 pm
           
            Tomasz,
           
            Para a sua primeira parte do feedback: não pega o comando executado
            mais recentemente e simplesmente para provar isso nós utilizamos 4
            modificadores diferentes para o mesmo comando.
            ($ ! ls $ ! ls -l $ ! ls -la $ ! ls -lA ).   Agora você pode verificar
            isso fornecendo as palavras-chave em qualquer ordem e em qualquer caso
            será exibido o mesmo resultado.   Mesmo que isso não esteja funcionando
            no ZSH como esperado, eu já mencionei que eu testei no BASH e a maioria
            deles pode não funcionar em outro shell.
           
            Para a segunda parte, o que você mencionou é uma HASH TAG na Linha de
            Comando do Linux e nós incluímos em um dos nossos artigos.   Você pode
            desejar lê-lo aqui: http://www.tecmint.com/linux-commandline-chat-server-and-remove-unwanted-packages/

    5. Manu says:
       May 16, 2015 at 8:55 am
      
       Artigo legal.
       Resposta:
          + Avishek Kumar says:
            May 18, 2015 at 11:30 pm
           
            Seja bem vindo Manu, Mantenha-se conectado!

    6. Tachyon says:
       May 16, 2015 at 4:40 am
      
       Grande post.   Obrigado, eu recompartilhei para G+
       Uma nota, "su" significa "switch user" e não "Suitable User".
       Nota menor.   Pelo menos isso ainda é representativo do que
       atualmente faz, diferente do que a maior parte das pessoas
       refere-se como "Super User", pensando que o comando concede
       apenas status de usuário "root", o que é absolutamente
       incorreto.
      
       Resposta:
          + Ravi Saive says:
            May 18, 2015 at 11:08 am
            @Tachyon,
            obrigado corrigido no texto acima..

Jamenson Ferreira Espindula de Almeida Melo
Usuário GNU/Linux nº 166197
https://linuxcounter.net/cert/166197.png

Impressão digital da chave:
234D 1914 4224 7C53 BD13  6855 2AE0 25C0 08A8 6180


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.26 (GNU/Linux)

iQEcBAEBCAAGBQJVXmQhAAoJECrgJcAIqGGA5xIIAKfXnn8D75spCHUhuESdz/6w
GiPFOOb9YQu7Ha22giyVozw8oTTLf99s5ObM6cg1omj6g5ogjbwW7LUgMFe88taH
O0EnWwCfiFtHx2zoEY8/wI56twILSCgr+9oMl3BQMzlgyTuSXnrMRzUbtR5SVLZy
z204ignWQfuUfVA7OqEq3CZRvpX+sKas2t88LuW/2kYWE4Nc3w6VVE/uACn5Q/Pg
75DcppcDTavB2jjGmwahg0jKtagcN+bYCUFSu0YBHDbkniXKkDDqbevD0RsheNoT
+Jp5E2oybTFce/eFz4Gqr6f0Z6Uje7+4iXSGd68fJbgUUTv//06ShxGF2TjKCY0=
=CbfT
-----END PGP SIGNATURE-----

Nenhum comentário:

Postar um comentário