Translate

terça-feira, 2 de outubro de 2012

Comandos Unix Parte II


Shell Scripts

Seqüências de comandos que se necessita repetir com grande frqüência podem ser colocados num arquivo que, ao ser ``executado'', ocasiona o disparo de cada um dos comandos da seqüência, na ordem indicada. Um arquivo desses é um shell script, cujo equivalente no MS-DOS são os arquivos ``.BAT''.
Mesmo que nunca se escreva nenhum, com certa freqüência é necessário analisar shell scripts a fim de elucidar o modo de uso de determinados comandos, ou de realizar diagnósticos. Suponhamos por exemplo que você não se lembre como usar um comando chamado xpatgen, mas esteja com um shell num diretório que contém scripts, que usam entre outros o xpatgen. Basta então buscar ocorrências dele nos scripts:

$ grep xpatgen *
patgen: xpatgen -cal_bl
Com isso sabemos que o script patgen executa o xpatgen, e relembramos o modo de executar esse comando, o que talvez já seja suficiente para a necessidade do momento.
Shell scripts utilizam com freqüência de variáveis de environment e de parâmetros de linha de comando. Assim, se ao analisar um script você se deparar com algo como $HOST, lembre-se de que nesse ponto será substituído o valor da variável HOST, e que $1 significa o primeiro parâmetro da linha de comandos$2 o segundo, e assim por diante.


Variáveis de Environment

Além dos parâmetros de linha de comandos como -l ou outros, pode-se também passar parâmetros a um programa através do uso de variáveis de environment. As mais comuns são:

  • PATH - Lista os diretórios (separados por ``:'') onde os executáveis serão procurados, tipicamente /bin/usr/bin e /usr/X11/bin, entre outros.
  • TERM - Tipo do terminal, por exemplo xterm ou vt100 (veja Configurando o Terminal).
  • DISPLAY - Display default para as aplicações Xwindows.
Para exibir o valor de uma delas pode-se usar echo, antepondo o operador $ ao nome da variável, por exemplo:

$ echo $TERM
Existem dois estilos de atribuição de valores a variáveis de environment, o do Bourne shell, usado pelo shksh e bash:

$ TERM=vt100; export TERM
e o do C shell, usado pelo csh e pelo tcsh:
% setenv TERM vt100


Uso de Metacaracteres

O metacaracter mais utilizado provavelmente é o ``*''. Por exemplo,

$ rm *
irá remover todos os arquivos do diretório corrente. É necessário prestar atenção a dois detalhes quando se usa metacaracteres:

  1. O caracter ``.'' não tem o significado de separador entre nome e sufixo que possui no MS-DOS, por isso ``*.*'' significa todos os arquivos em cujo nome ocorre ao menos um ponto.
  2. A expansão do metacaracter é feita pelo shell, e não pela aplicação, por isso o comando
    $ mv *.txt *.bak
    não irá surtir o efeito esperado de renomear todos os arquivos que terminam com ``.txt'' para ``.bak'' (para essa operação deve-se usar o comando for).
Os shells Unix aceitam também o metacaracter ``?'', que significa qualquer caracter e tambem intervalos, como [0-9] (qualquer dígito decimal), entre outros.

Uso de Expressões Regulares

Aplicativos Unix via de regra aceitam expressões regulares como argumentos de busca. Os usos mais freqüentes delas são bem ilustrados através do aplicativo grep. Nos casos abaixo ele será utilizado para buscar uma dada expressão em todos os arquivos do diretório corrente:

  1. Busca de ocorrências de algum dos anos da década de 80:
    $ grep "198[0-9]" * 
  2. Busca de uma ocorrência da palavra "yellow" seguida de uma ocorrência da palavra "page", separadas por zero ou mais caracteres quaisquer:
    $ grep -i "yellow.*page" * 
  3. Busca de uma das palavras "roget" ou "thesaurus":
    $ grep -i "roget\|thesaurus" * 
A sintaxe das expressões regulares pode variar um pouco, dependendo da plataforma e da ferramenta. Via de regra as diferenças consistem em proteger-se ou não alguns caracteres especiais, e nas extensões que algumas ferramentas introduzem. Note por exemplo, o uso do egrep, em comparação com o uso do grep acima:

$ egrep -i "roget|thesaurus" * 
Via de regra todas as ferramentas Unix que lidam com texto, como o more, o sed, e o vi, entre outros, aceitam expressões regulares como argumento de buscas.


Manipulando processos

Um processo é um programa em execução. Num computador que possui apenas uma cpu, na verdade apenas um processo pode estar sendo executado em cada instante. O que se faz é executar um processo durante uma fração fixa de segundo, congelá-lo e passar a executar um outro, e assim por diante, criando a ilusão de simultaneidade.
Através do comando ps pode-se examinar os processos correntes. Por exemplo:

$ ps
PID TTY STAT  TIME COMMAND
 45 v02 S     0:00 -bash
105 v02 R     0:00 ps
ps em geral omite muitos processos a fim de exibir uma saída limpa. Através das opções a e x (ou e no Solaris), pode-se exibir todos os processos correntes. O número de um processo é usado, por exemplo quando é necessário interromper prematuramente a sua execução, através do comando kill.
A finalidade primária do comando kill não é matar um processo, mas enviar um sinal para ele. O Unix possui diversos sinais predefinidos, como SIGHUP, SIGPIPE, SIGTERM, etc. O atendimento a um sinal entretanto é responsabilidade do processo, ou do programador que fez o programa, e por isso a forma com que cada processo reagirá a cada sinal poderá variar. A fim de se interromper a execução de um processo, deve-se enviar para ele o sinal SIGKILL:

 $ kill -SIGKILL 45
 $ kill -9 45
As duas formas acima em geral são equivalentes (o número associado a cada sinal pode variar com a plataforma).
O caracter ``&'' colocado ao final da linha de comandos instrui o shell para disparar o comando em background, a fim de que se possa continuar usando o shell mesmo antes desse comando encerrar a sua execução.
O comando nice faz com que um processo seja disparado com baixa prioridade.

 $ nice gzip -9 *
O comando nohup faz com que o processo sendo disparado se torne imune ao sinal SIGHUP. Em combinação com o &, ele permite o disparo de programas que permanecerão em execução mesmo após o logout do usuário. Exemplos:

 $ nohup gzip -9 * &
Através do comando at pode-se programar a execução de um comando para um horário determinado. Por exemplo:

 $ at now + 1 minute
 ls
 ctrl-d
O comando ls será dessa forma executado daqui a um minuto. Note que na linha seguinte do comando at o que se escreve é na verdade um shell script, terminado com control-d. Ao invés de digitá-lo, poder-se-ia lê-lo de um arquivo através do redirecionamento da entrada:

 $ at now + 1 minute <meuscript 
A execução periódica de um comando se faz através do cron, que é disparado no boot do sistema e monitora as tabelas de execução periódica de comandos de todos os usuários (a cada usuário corresponde uma tabela). Uma tal tabela é chamada crontab. Através dela pode-se especificar que um comando seja executado a cada hora, ou diariamente, ou semanalmente, etc. A edição, inspeção e remoção da crontab de um usuário é feita através do comando crontab, e opções -e-l e -d. Cada linha da crontab indica um comando e a periodicidade com que ele deve ser executado (minutos, horas, dias do mês, meses e dias da semana). Por exemplo:
 $ crontab -l
 40 07 * * * updatedb
 0 22 5 * * pagamento
 0 6,12,15,18 * * * fetch
 0 0 * * 6 backup
No caso a crontab contém três comandos. O updatedb deverá ser executado todos os dias às 7:40. O comando pagamento deverá ser executado às 22:00 do dia 5 de cada mês, e o backup será executado à zero hora de cada sábado.
Note que a crontab é um arquivo texto simples, e quando se executa o comando crontab com a opção -e, entra-se num editor de textos para editá-la. O editor de textos utilizado normalmente será o vi, ou aquele especificado na variável de environment EDITOR.

Nenhum comentário:

Postar um comentário