Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
| Ambos lados da revisão anterior Revisão anterior Próxima revisão | Revisão anterior | ||
| unix:shell_avancado [2019/08/12 16:19] – maziero | unix:shell_avancado [2024/11/21 17:50] (atual) – maziero | ||
|---|---|---|---|
| Linha 1: | Linha 1: | ||
| + | ====== UNIX: Uso avançado do Shell ====== | ||
| + | |||
| + | Neste texto são apresentados os principais conceitos associados a entradas e saídas padrão, como redirecionamentos e '' | ||
| + | |||
| + | ===== Entradas e saídas padrão ===== | ||
| + | |||
| + | A maioria dos comandos UNIX pode comunicar-se com o sistema através de descritores de arquivos especiais conhecidos como entradas e saídas padrão. Eles são: | ||
| + | |||
| + | * Entrada padrão ('' | ||
| + | * Saída padrão ('' | ||
| + | * Saída de erro ('' | ||
| + | |||
| + | {{ processo.png }} | ||
| + | |||
| + | Quando um comando é lançado sem indicar seu arquivo de trabalho, ele busca seus dados da entrada padrão. Por default, o shell onde o comando foi lançado associa o processo ao seu terminal, ou seja: a entrada padrão do processo é associada ao teclado e as saídas padrão e de erros à tela da sessão corrente. | ||
| + | |||
| + | {{ desv-terminal.png }} | ||
| + | |||
| + | Um exemplo de uso da entrada e saída padrão é o comando '' | ||
| + | |||
| + | < | ||
| + | $ rev | ||
| + | vamos fazer um teste | ||
| + | etset mu rezaf somav * | ||
| + | temos que achar um palindromo | ||
| + | omordnilap mu rahca euq somet * | ||
| + | opoetaamaateopo | ||
| + | opoetaamaateopo | ||
| + | ^D | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | No exemplo, as linhas marcadas com '' | ||
| + | |||
| + | < | ||
| + | $ sort | ||
| + | joao | ||
| + | maria | ||
| + | antonio | ||
| + | carlos | ||
| + | manoel | ||
| + | ^D | ||
| + | antonio carlos joao manoel maria | ||
| + | $ | ||
| + | </ | ||
| + | |||
| + | Normalmente o shell direciona a entrada padrão para o teclado e a saída padrão para a tela da sessão do usuário, mas ele pode ser instruído para redirecioná-las para arquivos ou mesmo para outros programas, como será visto na seqüência. | ||
| + | |||
| + | ===== Redireção para arquivos ===== | ||
| + | |||
| + | O shell pode redirecionar as entrada e saídas padrão de comandos para arquivos normais no disco, usando operadores de redireção, | ||
| + | |||
| + | {{ desv-arquivos.png }} | ||
| + | |||
| + | <note important> | ||
| + | A sintaxe de redireção é específica para cada shell, isto é, não é a mesma entre o C-Shell e o Bourne Shell; aqui será apresentada a sintaxe do shell Bash. | ||
| + | </ | ||
| + | |||
| + | Os principais operadores de redireção para arquivos são: | ||
| + | |||
| + | * Saída em arquivo: a saída padrão (// | ||
| + | |||
| + | < | ||
| + | $ ls > listagem.txt | ||
| + | </ | ||
| + | |||
| + | * Entrada de arquivo: a entrada padrão (//stdin//) pode ser obtida a partir de um arquivo usando o operador ''<'': | ||
| + | |||
| + | < | ||
| + | $ rev < listagem.txt | ||
| + | </ | ||
| + | |||
| + | * Uso combinado: os dois operadores podem ser usados simultaneamente. | ||
| + | |||
| + | < | ||
| + | $ rev < listagem.txt > listrev.txt | ||
| + | </ | ||
| + | |||
| + | * Concatenação: | ||
| + | |||
| + | < | ||
| + | $ ls /etc >> listagem.txt | ||
| + | </ | ||
| + | |||
| + | * Saída de erros: a saída de erros (// | ||
| + | |||
| + | < | ||
| + | $ ls /xpto > teste.txt | ||
| + | ls: /xpto: No such file or directory | ||
| + | |||
| + | $ ll /xpto 2> erro.txt | ||
| + | $ cat error.txt | ||
| + | ls: /xpto: No such file or directory | ||
| + | </ | ||
| + | |||
| + | * As saídas padrão e de erro podem ser redirecionadas de forma independente: | ||
| + | |||
| + | < | ||
| + | $ ll /xpto /etc/passwd > acerto.txt 2> erro.txt | ||
| + | |||
| + | $ cat error.txt | ||
| + | ls: /xpto: No such file or directory | ||
| + | |||
| + | $ cat acerto.txt | ||
| + | -rw-r--r-- 1 root root 2136 Mai 14 17:02 / | ||
| + | </ | ||
| + | |||
| + | * Além disso, a saída de erro pode ser sobreposta à saída padrão: | ||
| + | |||
| + | < | ||
| + | $ ll /xpto /etc/passwd > acerto.txt 2>&1 | ||
| + | |||
| + | $ cat acerto.txt | ||
| + | -rw-r--r-- 1 root root 2136 Mai 14 17:02 /etc/passwd ls: /xpto: No such file or directory | ||
| + | </ | ||
| + | |||
| + | * Forçar um desvio: Caso a saída seja redirecionada para um arquivo já existente, o shell recusa a operação indicando o erro (somente se a variável '' | ||
| + | |||
| + | < | ||
| + | $ ls > teste.txt | ||
| + | teste.txt: File exists. | ||
| + | |||
| + | $ ls >! teste.txt | ||
| + | |||
| + | $ ls >> novo.txt | ||
| + | novo.txt: No such file or directory | ||
| + | |||
| + | $ ls >>! novo.txt | ||
| + | </ | ||
| + | |||
| + | ===== Redireção usando pipes ===== | ||
| + | |||
| + | O shell permite a construção de comandos complexos através da combinação de vários comandos simples. O operador '' | ||
| + | |||
| + | {{ desv-pipes.png }} | ||
| + | |||
| + | É importante ressaltar que os comandos conectados são lançados simultaneamente pelo shell e executam ao mesmo tempo. O shell controla a execução de cada um para que não haja acumulo de dados entre os comandos (a cada pipe é associado um buffer de tamanho limitado). | ||
| + | |||
| + | A sintaxe usada para redireção é simples. Eis alguns exemplos: | ||
| + | |||
| + | < | ||
| + | $ ls -l /etc | more | ||
| + | $ ls -l /tmp | sort | more | ||
| + | $ ls -l /usr/bin | cut -c31-40 | sort | more | ||
| + | </ | ||
| + | |||
| + | O mecanismo de redireção de entrada/ | ||
| + | |||
| + | ===== Filtros ===== | ||
| + | |||
| + | Um filtro é basicamente um programa que lê dados da entrada padrão, realiza algum processamento e escreve os dados resultantes na saída padrão. Um exemplo simples de filtro seria: | ||
| + | |||
| + | <code c filtro.c> | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // lê caracteres em stdin e escreve em stdout, convertendo | ||
| + | // vogais minúsculas em ' | ||
| + | |||
| + | int main () | ||
| + | { | ||
| + | char c ; | ||
| + | |||
| + | c = getchar () ; | ||
| + | while (c != EOF) | ||
| + | { | ||
| + | switch (c) | ||
| + | { | ||
| + | case ' | ||
| + | case ' | ||
| + | case ' | ||
| + | case ' | ||
| + | case ' | ||
| + | c = ' | ||
| + | break ; | ||
| + | case ' | ||
| + | case ' | ||
| + | case ' | ||
| + | case ' | ||
| + | case ' | ||
| + | c = '#' | ||
| + | break ; | ||
| + | } | ||
| + | putchar (c) ; | ||
| + | c = getchar () ; | ||
| + | } | ||
| + | return (0); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Para compilar esse filtro basta digitar: '' | ||
| + | |||
| + | Existe um grande número de comandos UNIX bastante simples, cujo uso direto é pouco útil, mas que podem ser de grande valia quando associados entre si através de pipes. Esses comandos são chamados filtros, porque funcionam como filtros para o fluxo de dados. Eis alguns filtros de uso corrente: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * ... : qualquer programa que leia dados de stdin e escreva sua saída em stdout pode ser usado como filtro | ||
| + | |||
| + | Para conhecer melhor cada um dos comandos acima, basta consultar suas respectivas páginas de manual. | ||
| + | |||
| + | ===== Exercícios ===== | ||
| + | |||
| + | - Usando comandos e //pipes//, determine o número de linhas da página de manual do shell Bash. | ||
| + | - Determine quanto arquivos normais (não diretórios nem links) existem em ''/ | ||
| + | - Monte uma linha de comandos usando //pipes// para identificar todos os usuários proprietários de arquivos ou diretórios a partir de'' | ||
| + | * Use o comando '' | ||
| + | * Ordene a listagem obtida, usando o comando '' | ||
| + | * Remova as linhas repetidas, usando o comando '' | ||
| + | * Direcione a saída para o arquivo indicado '' | ||
| + | - Use o comando cut na saída de um comando ls -l para mostrar apenas as permissões dos arquivos no diretório /etc. Depois use sort e uniq para mostrar quantas permissões diferentes existem naquele diretório. | ||
| + | - Quantos arquivos invisíveis (iniciados com .) há na sua área HOME? | ||
| + | - Quantos diretórios há na sua área HOME? | ||
| + | - Liste todos os atributos de todos os arquivos de um diretório e utilize o cut para mostrar apenas suas permissões e seu nome. | ||
| + | - Liste todos os arquivos e seus atributos (somente os arquivos, diretórios não devem aparecer) do diretório /etc, ordenando a saída por data do arquivo, e guarde a saída no arquivo teste.txt na sua área. | ||
| + | - Mostre apenas o vigésimo arquivo do diretório /etc | ||
| + | - Mostre apenas os arquivos e diretórios para os quais você tem permissão de execução na sua área HOME. | ||
| + | - Acesse o servidor ssh.inf.ufpr.br. Utilize o comando finger para mostrar o Login de todos usuários cujo primeiro nome seja Daniel. | ||
| + | - Execute os comandos a seguir como usuário normal. Determine o que é stdin, stdout e stderr para cada comando (o conteúdo de cada fluxo para cada comando): | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - ''/ | ||
| + | - ''/ | ||
| + | - Confira seu resultado repetindo os comandos e atribuindo //stdout// para '' | ||
| + | - Observe as seguintes sequências de comandos e responda às perguntas: < | ||
| + | $ mkdir vazio | ||
| + | $ cd vazio | ||
| + | $ cp a b | ||
| + | cp: cannot stat ' | ||
| + | $ cp a b >a | ||
| + | </ | ||
| + | - Por que não há mensagem de erro após o segundo comando '' | ||
| + | $ date >a | ||
| + | $ cat a | ||
| + | Wed Feb 8 03:01:21 EST 2012 | ||
| + | |||
| + | $ cp a b | ||
| + | $ cat b | ||
| + | Wed Feb 8 03:01:21 EST 2012 | ||
| + | |||
| + | $ cp a b >a | ||
| + | $ cat b | ||
| + | </ | ||
| + | - Por que o arquivo '' | ||