Saltar para o conteúdo

Linux Essencial/Lição Combinação de comandos

Origem: Wikilivros, livros abertos por um mundo aberto.
  • Objetivo(s): Orientar sobre as possíveis combinações de comandos para a melhor utilização o sistema.
  • Direitos autorais e licença: Veja notas de direitos autorais e licença no final da lição.

Sequência de comandos

[editar | editar código-fonte]

Muitas vezes é necessário digitar uma sequência de comandos porém alguns deles requerem uma grande quantia de tempo para finalizar e não podemos esperar que terminem para entrar com os próximos comandos. Com essa ideia foi criado a sequência de comandos que visa passar de uma única vez uma lista de comandos para o sistema e, com isso, evitar que o próprio usuário digite-as, ganhando tempo, pois o sistema ao terminar um comando já sabe o que deverá fazer.

Os comandos deverão ser separados por ";", pois assim o sistema saberá onde quebrar os comandos antes de prosseguir. É necessário entender que a execução dos comandos acontecem de forma independente e sequencial, apesar de estarem na mesma linha. Dessa forma o sistema espera que o ultimo comando antes de ";" termine para que execute o próximo. Se algum dos comandos estiver errado o sistema tentará executá-lo e se não conseguir, retornará um erro e continuará com a leitura dos outros comandos. Sintaxe:

comando1; comando2; comando3; comandox...

Exemplo:

/$ls; cd /home; cd /tmp; ls teste[123]
tmp
teste2
/tmp$
/$ls; cd /root; ls; cd /tmp; ls teste[123]
tmp
bash: cd: /root: Permissão Negada
tmp
teste2
/tmp$

Nesse exemplo, primeiramente foi executado o comando "ls". Logo após o usuário tentou entrar na pasta do super-usuário, sendo, por falta de permissões, barrado. O segundo comando "ls" deveria listar o conteúdo da pasta do super-usuário, mas como o comando anterior (cd) falhou, o "ls" listou o conteúdo da pasta, anterior ao comando (a do próprio usuário). Logo após, o comando cd /tmp mudou o diretório corrente para /tmp, listando o conteúdo que tivesse nome conforme o padrão especificado. O retorno do shell permite observar que o comando foi finalizado, e que ficará dentro da pasta /tmp.

Redirecionamento e pipes

[editar | editar código-fonte]

O computador é formado por diversos componentes, muitas vezes conhecidos como periféricos, tendo como principais o monitor e o teclado. Estes são normalmente as principais formas de entrada e saída de dados no sistema.

Esses dois componentes formam o principal meio de comunicação entre usuário e o computador, com funções bem distintas entre eles. O teclado fornece a entrada de um determinado dado para o sistema, e o monitor a saída da informação.

Existem ainda outros meios de comunicação entre o usuário e o computador que podem servir de entrada de dados como o mouse (em diversos programas, na maioria gráfico), o scanner, a rede, o CD-ROM ou DVD; e como saída (além do monitor) a impressora, a rede, o CD-ROM ou DVD.

Os sistemas UNIX, incluindo o GNU/Linux, lidam com 3 dispositivos básicos:

  • Entrada padrão, também conhecida por STDIN
  • Saída padrão, também conhecida por STDOUT
  • Saída de erro padrão, também conhecida por STDERR

Os sistemas UNIX possuem um conceito interessante, no qual “tudo é um arquivo”. Esse conceito permite escrever, em dispositivos externos, exatamente da mesma maneira que se escreve em arquivos. Consequentemente, os dispositivos básicos mencionados acima são também arquivos.

Programas UNIX, incluindo o shell, lidam com arquivos através de descritores, ou seja, números que representam um determinado arquivo que está aberto para leitura e/ou escrita.

A entrada padrão, a saída padrão e a saída de erro padrão, também possuem esses descritores. Segue uma tabela com o resumo desses dispositivos, incluindo o número dos descritores de arquivo.

Dispositivo Apelido Número do Descritor de Arquivo Mapeado por Padrão Para
Entrada padrão STDIN 0 Teclado
Saída padrão STDOUT 1 Monitor
Saída de erro padrão STDERR 2 Monitor

Redirecionamento

[editar | editar código-fonte]

O uso do redirecionamento é muito simples. Mesmo monitor sendo a forma padrão de saída de informações, e o teclado a forma padrão de entrada, podemos alterar a saída e entrada padrão para utilizarmos por exemplo um arquivo ou outro dispositivo.

Executar determinadas operações e direcionar o resultado para um arquivo pode ser bem mais conveniente que ter de copiá-las manualmente da tela para um arquivo. O conteúdo desses arquivos (o resultado gerado por determinado comando), pode então ser manipulado normalmente, sendo possível, por exemplo, a pesquisa de algum valor.

Algo que é bastante usado é o redirecionamento do comando dpkg -l, que irá listar todos os pacotes instalados no sistema (isto é um exemplo, a funcionalidade de dpkg -l será explanada em tópicos a seguir).

Esse comando, quando digitado no interpretador de comandos, gerará na tela uma listagem dos pacotes instalados, geralmente com velocidade bem superior à nossa capacidade de leitura.

O redirecionamento permitirá que em vez de escrever na saída padrão (monitor) o mesmo possa ser redirecionado para outras saídas (arquivo ou impressora). O inverso também é valido, sendo possível no momento da leitura do conteúdo do arquivo redirecionar sua saída para outro arquivo (um arquivo servirá de entrada de dados para outro arquivo).

Sintaxe:

comando redirecionamento arquivo [redirecionamento] [arquivoX]

Comando: é a opção a ser realizada pelo sistema, podendo o mesmo gerar informações de entrada ou saída do sistema.

Redirecionamento: pode ser representado pelos sinais invertidos de maior (>) ou menor (<), sendo que o lado maior irá representar o fornecedor da informação e o lado menor o receptor.

Arquivo: é a saída gerada pelas informações, sendo que o arquivo será gerado no momento do redirecionamento. Múltiplos redirecionamentos simultâneos são possíveis, como por exemplo, redirecionamento de entrada e de saída, ou de saída e saída de erro padrão.

Exemplo:

#dpkg -l > pacotes.txt

No exemplo, a saída gerada pelo comando “dpkg -l” foi redirecionado para o arquivo chamado pacotes.txt.

É possível fazer o redirecionamento do arquivo gerado para um outro arquivo, por exemplo, colocá-lo em ordem alfabética:

#sort < pacotes.txt > pacotesordenados.txt

Ao término desse comando, será criado um novo arquivo chamado pacotesordenados.txt, tendo ainda o seu conteúdo ordenado em relação ao originário pacotes.txt.

NOTA: nunca utilize o redirecionamento para o mesmo arquivo, pois o mesmo deve ser comparado linha por linha antes de ser escrito, e se for o mesmo arquivo todas as informações geradas dentro dele serão perdidas.

Somente os erros que estão acontecendo em um determinado arquivo poderão ser redirecionados. Por exemplo, um programa ao ser chamado, gera algumas informações, e uma delas pode ser de erro o que torna importante para o administrador saber capturá-las.

A saída de erro padrão, nos interpretadores bash e ksh, pode ser redirecionada utilizando o valor de seu descriptor de arquivo, ou seja, o número 2, antes do redirecionamento.

Exemplo:

#./programaX 2> possível_erro.txt

No exemplo acima o “./” serve para informar ao sistema que deverá ser executado o programaX cujo executável está no diretório corrente. O “2>” envia possíveis mensagens de erro para o arquivo possível_erro.txt.

Além do "<" e do ">" é possível também utilizar o "<<" e o ">>". O uso destes é semelhante ao que vimos anteriormente.

O ">>" redireciona a saída de um programa/comando/script para algum dispositivo ou final de arquivo. A diferença entre o redirecionamento duplo e o simples é que, quando usado com arquivos, o redirecionamento duplo adiciona a saída do comando ao final do arquivo existente em vez de substituir seu conteúdo como faz o redirecionamento simples. No exemplo a seguir a saída do comando "ls" seria adicionada ao final do arquivo lista.txt.

#ls >> lista.txt

O "<<" é especialmente usado em conjunto com o comando cat, mas possui, também, outras aplicações. A seguir um exemplo de uso:

cat << MarcadorDeFim?

Logo após digitar o comando, será apresentado na tela (logo abaixo) o sinal de prompt para que você digite qualquer texto. Escreva qualquer texto, linha após linha. Quando você quiser terminar, na última linha escreva MarcadorDeFIm. Esse marcador de fim pode ser qualquer sequência de caracteres. É usual usar EOF (End Of File), mas nada impede de usar outros marcadores. Ao pressionar a tecla ENTER, o shell vai apresentar na tela o que você acabou de digitar nas linhas acima do texto MarcadorDeFim.

A ideia principal do uso do comando pipe ("|") é fazer com que os comandos trabalhem em conjunto. Um comando trabalhando sozinho geralmente é limitado quanto a sua funcionalidade, revelando uma outra característica dos sistemas operacionais UNIX: “faça apenas uma coisa, mas faça-a bem”.

Os pipes facilitam o trabalho em equipe dos utilitários UNIX. Nesse cenário, cada aplicativo executa determinada operação no arquivo, e passa o resultado para o próximo utilitário. Pense em pipes como uma linha de produção, onde as determinadas etapas são realizadas por diferentes utilitários UNIX.

Lembre-se da terminologia UNIX, na qual cada programa lê de uma determinada entrada padrão e escreve para uma saída padrão. Com o uso dos pipes, a saída do primeiro programa é automaticamente lançada para ser a entrada padrão do segundo comando. Após trabalhar nos dados que recebeu, o segundo programa joga esses resultados para sua saída padrão, que é na verdade a entrada padrão do terceiro programa nessa “linha de produção”.

Ao chegar no fim da linha, o último programa simplesmente joga seus resultados para sua saída padrão, exatamente igual aos demais. Essa saída, é geralmente o monitor, mas nada nos impede de usar os recursos de redirecionamento que aprendemos, e termos o resultado de todo o processo armazenado em um arquivo.

Sintaxe:

comando1 | comando2 | comando3 | ... | comandoX

Os comandos podem ser ligados em série sem restrição de quantidade, mas com restrição quanto ao uso, pois uma saída gerada será a entrada de outra.

Exemplo:

# ls /etc | more
CORBA
DIR_COLORS
LexmarkZ11
Muttrc
TextConfig
X11
adjtime
aide.conf
aliases
aliases.db
alternatives
amd.conf
amd.net
apt     
at.deny
atalk
--Mais--

No exemplo acima, foi possível interromper a listagem do conteúdo do diretório /etc com uma parada quando a tela ficou cheia, sem ocorrer a perda de algum arquivo importante na busca.

A ferramenta "tee" permite o redirecionamento em ambas direções, ou seja, enquanto que o redirecionamento comum é feito ou para a saída padrão ou para um arquivo, o tee permite realizar as duas coisas ao mesmo tempo. O comando "tee" permite que a saída de um comando seja gravada em um arquivo ao mesmo tempo em que é exibida na tela.

Sintaxe:

tee [opção] arquivo

Opção:

-a - quando solicitada a entrada padrão que for gerada para o arquivo, o "tee" deverá ser posto ao final para evitar sobrescrever dados já existentes.

O seu uso é muito comum em tarefas do dia-a-dia, por exemplo, em teste de uso de alguma ferramenta, ou preparação de arquivo possibilitando ainda a sua leitura.

Exemplo:

# dpkg -l > pacotes.txt

# cat pacotes.txt | sort | tee pacotesordenados.txt O exemplo acima teria quase o mesmo efeito de:

# dpkg -l > pacotes.txt
# sort < pacotes.txt > pacotesordenados.txt

Para maiores detalhes sobre o comando "tee" leia o tópico sobre redirecionamento.

A diferença entre os dois exemplos, é que com o uso de "tee" é possível visualizar o que foi feito, e no segundo exemplo seria necessário utilizar um comando de processamento de texto como o comando cat.

O "grep" é um comando que procura por um texto dentro de um arquivo ou no dispositivo de entrada padrão.

sintaxe:

grep [expressão] [arquivo] [opções]

Opções:

-A [número] Mostra o [número] de linhas após a linha encontrada pelo grep.

-B [número] Mostra o [número] de linhas antes da linha encontrada pelo grep.

-f [arquivo] Especifica que o texto que será localizado, está no arquivo [arquivo].

-i, --ignore-case Ignora a diferença entre maiúsculas e minúsculas no arquivo procurado.

-n, --line-number Mostra o nome de cada linha encontrada pelo grep.

-U, --binary Trata o arquivo que será procurado como binário.

Exemplo:

$ grep root /etc/group

root:x:0:

Combinado com o pipe o "grep" é muito útil para filtrar saída de comandos. No exemplo a seguir, a saída de ps aux é direcionada para o comando "grep" para que seja filtrada. É muito útil pra se usar com outros comandos de localização.

Exemplo:

$ ps aux | grep root

root         1  0.0  0.0   2844  1688 ?        Ss   13:00   0:02 /sbin/init
root         2  0.0  0.0      0     0 ?        S<   13:00   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S<   13:00   0:00 [migration/0]
root         4  0.0  0.0      0     0 ?        S<   13:00   0:00 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   13:00   0:00 [watchdog/0]
root         6  0.0  0.0      0     0 ?        S<   13:00   0:00 [migration/1]
root         7  0.0  0.0      0     0 ?        S<   13:00   0:00 [ksoftirqd/1]
root         8  0.0  0.0      0     0 ?        S<   13:00   0:00 [watchdog/1]
root         9  0.0  0.0      0     0 ?        S<   13:00   0:00 [events/0]
root        10  0.0  0.0      0     0 ?        S<   13:00   0:00 [events/1]
root        11  0.0  0.0      0     0 ?        S<   13:00   0:00 [khelper]
root        46  0.0  0.0      0     0 ?        S<   13:00   0:00 [kblockd/0]
root        47  0.0  0.0      0     0 ?        S<   13:00   0:00 [kblockd/1]
root        50  0.0  0.0      0     0 ?        S<   13:00   0:00 [kacpid]

Exercícios de Revisão

[editar | editar código-fonte]

1. Crie um arquivo listando o conteúdo do diretório /etc dentro do /tmp.

2. Crie um arquivo parecido com o anterior, porém apresentando na saída padrão o conteúdo conforme ele é gravado.

3. Liste o conteúdo do diretório /dev, incluindo os arquivos ocultos, e redirecione o resultado para a o arquivo dev.txt.

4. Crie uma pasta com o nome dir1, acesse a pasta, crie um arquivo chamado arq.txt. Faça uma cópia do arquivo e remova o original utilizando apenas 1 linha para realizar o comando.