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 '' | ||