% JLdL 20May01.
%	Copyright (C) 2000-2002 by Jorge L. deLyra.
% Mail: <delyra@latt.if.usp.br>. Web: "http://latt.if.usp.br".
% Este documento pode ser copiado e/ou distribuído livremente.
% Ver os termos e condições nos arquivos do sub-diretório web/.
% This document may be copied and/or distributed freely. See the
% _ terms and conditions in the files in the web/ subdirectory.

\documentclass[12pt]{article}
\usepackage[brazil]{babel}\usepackage[latin1]{inputenc}

\title{ {\huge\bf FMA 215} \\ Aula 6: Processos e Shell Jobs }

\author{Prof. Jorge L. deLyra}

\date{25 de Abril de 2002}

\begin{document}\maketitle

\section{Alguns Conceitos Relevantes}

 Nesta aula vamos lidar com os processos que rodam no sistema, bem como a
 submissão de ``jobs'' através da shell, ou seja, a execução de processos
 no ``background'', sem que o seu terminal fique preso a ele. Passaremos
 também pelo conceito de ``pipeline'' de processos, que nos permitirá
 combinar diversos programas para obter novas ações sobre os elementos do
 sistema, mais variadas, mais complexas, para fins mais específicos. Desta
 forma estaremos dando uma primeira olhada em como as coisas {\em
 acontecem} no sistema. É claro que já estivemos usando estes elementos
 nas aulas anteriores, pois o seu uso é inerente à operação do sistema,
 mas nesta aula vamos nos concentrar em entender como eles funcionam.

 \paragraph{Processo:} um processo é uma instância de um programa que está
 rodando no sistema. Um mesmo programa pode estar rodando várias vezes ao
 mesmo tempo, em vários processos diferentes. Por exemplo, um mesmo editor
 de texto pode estar sendo usado por vários usuários ao mesmo tempo. Cada
 processo é identificado por um número único entre todos que estão
 rodando, ao qual chamamos de PID (process identification). Além disso,
 ele está sempre associado a um usuário, ao qual pertence. Ou seja, há uma
 noção de ownership para processos, assim como para arquivos.

 Esta é uma noção de ownership do tipo do ownership de user para arquivos.
 Existe também um conceito de grupos para processos, mas ele não é muito
 importante no que diz respeito ao que nos interessa como usuários do
 sistema. Existe um outro tipo de relação entre processos, de caráter
 hierárquico tipo pais-e-filhos, que é mais relevante. Cada processo é
 ``filho'' (child) de algum outro processo, que chamamos de ``pai'' ou de
 parent-process. Isto estabelece um tipo de estrutura hierárquica entre os
 processos que, em geral, está ligada ao fato de que um processo inicia
 outros, que são denominados seus filhos (children). A raiz da árvore
 deste sistema hierárquico é o processo {\tt init}, que tem número PID 1.
 Este é o processo inicial que inicializa todo o sistema quando ele é
 colocado no ar.

 Não se deve confundir este processo inicial com o kernel. O kernel é de
 fato um programa que está rodando na máquina, mas ele não é um processo e
 sim o programa subjacente que controla todos os processos. Assim como ele
 controla os dispositivos de armazenamento e de entrada e saída, o kernel
 também controla a utilização da memória RAM e do CPU, submetendo a eles
 outros programas para serem executados. Estes outros programas aparecem
 como processos dentro da estrutura de controle estabelecida pelo kernel.
 O programa {\tt init} é o primeiro que é executado pelo kernel logo após
 o boot deste, tendo a finalidade de colocar para rodar todos os outros
 programas que são necessários para que tenhamos um sistema operacional
 multi-user e multi-tasking completo em funcionamento.

 \paragraph{Jobs:} a shell pode rodar vários programas ao mesmo tempo para
 você. Ela tem um sistema de controle dos processos que tenham sido
 submetidos através dela, os quais são chamados de ``jobs''. O sistema de
 controle em si é denominado ``job control''. Com este sistema, pode-se
 iniciar, suspender e re-iniciar processos, terminar processos submetidos
 anteriormente, desconectar e reconectar processos ao terminal e listar os
 jobs, ou seja, os processos que estão sob o controle da shell.

 Esta capacidade da shell é muito útil para lidar com a situação na qual
 se está rodando um determinado programa e aparece a necessidade de se
 suspender momentaneamente esta atividade para executar alguma outra,
 voltando-se posteriormente a ela. Basta suspender o processo, o que
 libera o terminal para outras tarefas, reconectando posteriormente o
 terminal ao processo que foi suspenso. Este sistema também é útil quando
 é necessário deixar um ou mais programas rodando permanentemente sem
 conexão com o terminal, como é o caso, por exemplo, para um relógio.

 \paragraph{Pipeline:} o conceito de {\bf pipeline} de comandos é um dos
 conceitos importantes do sistema. Uma pipeline é um processo pelo qual
 dois ou mais programas podem ser executados de forma coordenada, em uma
 determinada ordenação, de forma que o output de cada um é redirecionado
 como input do próximo. Assim, o conjunto dos programas que são executados
 desta forma passa a se comportar como um novo programa, com o input
 direcionado ao primeiro programa e o output vindo do último. Desta forma
 podemos efetivamente combinar a ação de vários executáveis binários de
 forma muito fácil e flexível, em vez de modificar e recompilar os
 respectivos programas, ou mesmo escrever novos programas para as tarefas
 que se queira realizar.

 Em geral as shells permitem a montagem de pipelines de comandos, que
 podem ser usadas na linha de comando ou em programas de shell (shell
 scripts). A forma de se fazer isto é usar o caracter {\tt |} para separar
 os diversos comandos, em ordem, na linha de comando. Por exemplo, para
 ver uma longa lista de arquivos, que não cabe no terminal, pode-se usar
 um paginador, um programa que mostra uma página de cada vez. Um exemplo
 disto é a combinação {\tt ls -l /etc | more}, onde o comando {\tt more} é
 o paginador. Com o uso deste programa pode-se passar de página em página
 do output do comando {\tt ls -l} usando-se a barra de espaço do teclado.

\section{Tarefas}

 Este conjunto de tarefas deve ser realizado no sistema de janelas X11, o
 que irá possibilitar o uso de âncoras visuais que facilitarão a
 compreensão dos elementos com os quais vamos lidar.

 Para trabalhar com este tipo de interface gráfica, é necessário lembrar
 que existe nele o conceito de {\bf foco}, como já vimos na aula anterior:
 a janela que tem o foco é aquela que recebe o que se digita no
 teclado. Para colocar o foco em uma determinada janela, a melhor forma é
 clicar o botão esquerdo do mouse na parte central da barra superior da
 janela, o que também a colocará acima de outras janelas que a estejam
 cobrindo parcialmente.

 Às vezes pode ser necessário também movimentar uma janela para que ela
 fique mais visível. Para fazer isto, basta clicar e segurar o botão
 esquerdo do mouse sobre a parte central da barra superior da janela e
 movimentar o mouse, que carregará a janela consigo. A nova posição da
 janela será aquela na qual o botão do mouse for solto. Neste momento ela
 terá também o foco, ou seja, estará recebendo o input do teclado.

\begin{enumerate}

 \item Faça um login no sistema, usando o sistema de janelas X11. Caso o
 computador esteja com o Linux rodando mas a bandeira de login do sistema
 X11 não esteja visível, digite {\tt [Ctrl]-[Alt]-F7}. Isto o levará de
 qualquer dos consoles virtuais para o sétimo, onde em geral estará
 rodando o sistema X11.

 \item Quando você entrar, será aberto para você um terminal {\tt xterm},
 que aparecerá como uma janela em algum lugar da tela. Esta janela tem um
 papel especial em sua seção, se ela for eliminada toda a seção terminará
 e o X11 será reciclado, aparecendo novamente a bandeira de login. Para
 evitar que você termine sua seção acidentalmente, vamos evitar usar esta
 janela por enquanto.

 Abra duas outras janelas {\tt xterm} para uso nestas tarefas. Para fazer
 isto, clique e segure o botão esquerdo do mouse sobre o fundo da tela.
 Aparecerá um menu, o primeiro ítem do qual abre um novo terminal. Leve o
 cursor do mouse para cima deste primeiro ítem e solte o botão da
 esquerda, o que causará o aparecimento de uma nova janela de terminal.

 Tendo aberto os dois novos terminais, iconize o terminal original,
 clicando o botão esquerdo do mouse no botão que contem um pequeno
 quadradinho, o penúltimo à direita na barra superior da janela. Organize
 os dois novos terminais na tela, mudando suas posições, até que se tenha
 boa visibilidade de ambas as janelas e que seja possível passar o foco
 facilmente de uma para a outra.

 \item Execute, em uma das duas janelas, o comando {\tt ps}. Você consegue
 reconhecer cada um dos processos que estão rodando e identificar a que
 janelas cada um está associado?

 \item Execute, na outra janela, o comando {\tt xclock}. Vai aparecer em
 sua tela um relógio. Observe que o terminal fica ``preso'', não responde
 mais ao seu input no teclado, não mostra mais o prompt quando você aperta
 a tecla {\tt [Enter]}. Olhe os processos de novo, no outro terminal.

 \item Coloque o foco no terminal onde você está rodando o relógio e
 digite {\tt [Ctrl]-C}. Isto significa segurar a tecla {\tt [Ctrl]}
 (control) enquanto você digita uma vez a tecla da letra {\tt C} (ou {\tt
 c}). Apesar de que em geral indicamos este tipo de coisa usando letras
 maiúsculas, não se deve apertar a tecla {\tt [Shift]}. Caso isto seja
 necessário estará indicado explicitamente. Observe o que acontece com o
 relógio. Verifique a situação dos processos no outro terminal.

 \item Execute mais uma vez, na mesma janela que usou antes, o comando
 {\tt xclock}. Para desconectar o seu terminal do processo que foi
 iniciado, digite a combinação {\tt [Ctrl]-Z}. Trata-se de um caracter de
 controle que faz com que um sinal seja enviado pela shell ao processo,
 provocando a sua suspensão temporária. Observe que você ganha de volta o
 acesso de input à janela. Verifique a situação dos processos no outro
 terminal.

 \item Voltando ao terminal onde está rodando o {\tt xclock}, execute o
 comando {\tt jobs}. Ele irá mostrar todos os processos que estão sendo
 administrados pela shell que está rodando neste terminal. Examine o
 output do comando e veja se dá para entender o que aparece lá.

 \item É possível rodar um programa de forma que ele já se inicie sem
 conexão com o terminal. Para fazer isto, na mesma janela que está usando
 para rodar o primeiro relógio, rode um segundo relógio usando o comando
 {\tt xclock \&}. Observe que desta vez o seu terminal ficou livre para
 outras tarefas.

 \item Execute de novo o comando {\tt jobs} e examine o resultado.
 Verifique a situação dos processos no outro terminal. Observe os dois
 relógios durante alguns minutos e verifique o que acontece com eles.
 Você sabe porquê os dois se comportam de forma diferente?

 \item Para por para rodar de fato o job que está suspenso no background,
 como indicado no output do comando {\tt jobs}, basta executar o comando
 {\tt bg \%<número-do-job>}. O número do job é o que aparece entre chaves
 no output do comando {\tt jobs}. Execute de novo este comando, examine o
 resultado e verifique a situação dos processos no outro terminal. Espere
 mais alguns minutos e verifique como se comportam os relógios agora.

 Um processo estar no ``background'' significa que ele está rodando sob a
 administração da shell, sem, entretanto, que o sistema de input da sua
 sessão esteja ligado permanentemente a ele. Dizemos que um processo que
 esteja sendo rodado pela shell e que esteja ligado ao input do teclado
 está rodando no ``foreground''.

 \item Execute o comando {\tt jobs -l}, que irá listar os números de
 identificação (PID) dos processos associados a cada um dos jobs. No outro
 terminal, olhe os processos com o comando {\tt ps}, identificando aquele
 que corresponde ao primeiro job. Em seguida, elimine este processo usando
 o comando {\tt kill <número-do-processo>}. O número do processo aparece
 tanto no output do comando {\tt jobs -l} quanto no do comando {\tt ps}. O
 que acontece com o relógio? Olhe de novo os processos e execute de novo o
 comando {\tt jobs} no outro terminal.

 \item Observe que, ao contrário do comando {\tt ps}, o comando {\tt jobs}
 dá resultados que são específicos da shell sob a qual está rodando. O
 comando {\tt jobs} não é um programa como o comando {\tt ps}, que está
 num arquivo que a shell lê e roda. Ele é o que chamamos de um ``comando
 intrínseco'' da shell, ou um ``shell built-in'', um comando interno do
 programa que chamamos de ``shell''. Em cada tipo de shell existe um
 número relativamente pequeno de comandos deste tipo. Execute o comando
 {\tt jobs} em ambos os terminais e verifique a diferença nos outputs de
 cada um.

 \item Para reconectar um job ao seu terminal, você executa o comando {\tt
 fg \%<número-do-job>}. Faça isto com o segundo relógio. Observe que o seu
 terminal ficou preso de novo. Você pode colocar ele no background de novo
 digitando {\tt [Ctrl]-Z}. Para reconectar o job mais uma vez ao seu
 terminal, basta dar agora o comando {\tt fg} sem argumento. Havendo
 apenas um job, todos os comandos de controle de jobs vão se aplicar a ele
 de forma automática. Elimine o segundo relógio usando {\tt [Ctrl]-C} ou o
 comando {\tt kill}.

 \item Num dos dois terminais que você abriu, rode o comando {\tt ps} com
 as opções {\tt a}, {\tt u} e {\tt x}, ou seja, use o comando da forma
 {\tt ps aux}. O comando {\tt ps} tem a peculiaridade de não exigir (na
 verdade, de não querer) os sinais de {\tt -} antes das opções. Se você os
 colocar, ele entende o input e executa corretamente, mas dá um aviso de
 ``deprecated'', o que significa que um dia ele vai parar de aceitar esta
 forma de se colocar as opções. Em geral, com ou sem os sinais de {\tt -},
 quando um comando é submetido com várias opções, você pode juntar as
 opções, ou seja, em nosso caso {\tt ps aux} é equivalente a {\tt ps a u
 x}.

 Esta forma do comando vai colocar na tela uma lista de todos os processos
 que estão rodando no sistema. A opção {\tt a} significa ``all'', ou seja,
 não apenas os seus processos, mas também os de outros usuários. A opção
 {\tt u} faz com que o comando mostre o usuário ao qual pertence cada
 processo. A opção {\tt x} inclui na lista os processos que não estejam
 conectados a um terminal. Caso você queira descobrir mais sobre este
 comando, olhe a sua página do manual, executando {\tt man ps}.

 Provavelmente você vai descobrir que a lista que aparece não cabe toda no
 seu terminal. Em geral há um número considerável de processos rodando em
 qualquer sistema, mesmo quando ele não está fazendo nada particularmente
 notável. A maior parte destes processos é do usuário root, o que indica
 que se trata de processos internos do sistema ou de serviços mantidos
 pelo sistema, que não pertencem a nenhum usuário em particular.

 \item Para poder olhar toda a lista de processos de uma forma controlada,
 vamos agora usar o conceito de {\bf pipeline} de comandos, que é um dos
 conceitos importantes do sistema. Desta forma, redirecionamos o output do
 comando {\tt ps aux}, que é uma lista um tanto longa, para o input de um
 outro programa, um paginador como o programa {\tt more}, que nos permita
 olhar uma página de cada vez. Faça isto, executando a pipeline {\tt ps
 aux | more}, passando de cada página para a seguinte com a barra de
 espaço do teclado, ou indo de linha em linha com a tecla {\tt [Enter]}.

 \item O comando {\tt more} também pode ser usado diretamente para paginar
 um arquivo qualquer. Use-o da forma {\tt more /etc/passwd} para verificar
 este fato. Tente também {\tt ypcat passwd | more}, caso o seu sistema
 esteja rodando o sub-sistema NIS (Network Information Service, vamos ver
 isto mais tarde). Alguns comandos e programas já paginam o seu output de
 forma automática como, por exemplo, o comando {\tt man}. Execute o
 comando {\tt man more} para verificar este fato.

 O comando {\tt man} não tem um código de paginação interno. Em vez disso,
 ele está fazendo, internamente, uma pipeline e usando um programa de
 paginação. Note como, desta forma, economiza-se muita repetição de
 programação no sistema. Podemos ter dois ou três programas diferentes de
 paginação, mas não é necessário repetir todo o código de paginação em
 cada programa que necessitar deste tipo de ação sobre os dados de saída.

 \item O comando {\tt ps} nos permite olhar os processos do sistema num
 determinado momento. Há também uma utilidade, chamada {\tt top}, que nos
 permite monitorar os processos de forma mais detalhada, pois ele fica
 rodando, atualizando o seu output a intervalos regulares, mostrando os
 processos em ordem decrescente de tempo de CPU utilizado por cada um. Ou
 seja, ele nos mostra os processos mais ativos do sistema por ordem
 decrescente de atividade. Desta forma, ele nos dá uma boa idéia de como
 está a carga de processos no sistema. Execute este aplicativo em um dos
 dois terminais que você abriu, digitando {\tt top}. Observe durante algum
 tempo o output que aparece na tela.

 \item No outro terminal, vamos rodar um programa que vai consumir uma
 grande quantidade de tempo de CPU, para ver o que acontece no output do
 comando {\tt top}. Execute no outro terminal o comando {\tt cat /dev/zero
 > /dev/null}. Como o arquivo {\tt /dev/zero} não é de fato um arquivo
 comum e sim uma conexão com o gerador de zeros binários do kernel, este
 comando vai usar muito tempo de CPU. O resultado de toda esta atividade é
 uma grande quantidade de zeros, que vão ser descartados, pois o output
 está re-direcionado para {\tt /dev/null}.

 Não se recomenda rodar algo assim durante a operação normal do sistema,
 pois trata-se de um exemplo paradigmático de atividade 100~\%
 ineficiente, que vai consumir grande quantidades de recursos do sistema
 com absolutamente nenhum resultado. Observe o output do comando {\tt top}
 que está rodando no outro terminal durante algum tempo. Depois disto,
 interrompa o processo que você está rodando neste terminal, digitando
 {\tt [Ctrl]-C}. Volte a observar mais um pouco o output na outra janela.

 \item Termine o comando {\tt top} digitando a letra {\tt q} no terminal
 onde ele está rodando. O comando {\tt top} também pode ser rodado num
 terminal comum, fora do sistema de janelas X11. Para fazer isto, é
 necessário que você faça um novo login no sistema, em um dos consoles de
 caracteres. Ao fazer isto, não saia da sua seção X11, você vai passar a
 ter duas seções independentes no sistema, uma no X11 e outra num console
 de caracteres.

 Para fazer isto, digite {\tt [Ctrl]-[Alt]-F1}, o que o levará para o
 primeiro console virtual, que é o terminal {\tt tty1} do sistema. Faça um
 login neste terminal. Este console é agora um novo terminal de acesso ao
 sistema, onde está rodando mais uma shell pertencente a você. Rode o
 comando {\tt top} neste terminal. Verifique que ele funciona exatamente
 como você já viu antes ao rodá-lo dentro do sistema de janelas X11.

 \item Deixe o {\tt top} rodando no primeiro console e volte ao sistema
 X11, digitando {\tt [Alt]-F7} (ou {\tt [Ctrl]-[Alt]-F7}, tanto faz,
 quando você está executando isto fora do sistema X11). Execute o comando
 {\tt ps} dentro de uma das duas janelas de terminal que ainda estão
 lá. Você consegue identificar os processos que se referem à sua outra
 seção? Mate o processo do comando {\tt top} com o comando {\tt kill} e
 volte ao primeiro console para verificar o que aconteceu. Termine sua
 seção no console executando o comando {\tt exit}. Observe a bandeira de
 login do terminal de caracteres voltar a aparecer e depois volte ao X11.

 \item Existe outra forma de se executar um processo, que às vezes é útil.
 Trata-se do uso do comando {\tt exec}, que é outro ``built-in'' da shell.
 Para usar este comando, basta executar {\tt exec <programa>}. Quando
 executamos programas usando este comando, a shell comete um tipo de
 suicídio: em vez de rodar o programa como um novo processo, ela roda o
 programa em lugar dela mesma e morre. Para testar isto, execute o comando
 {\tt exec top} em um dos dois terminais que você tem no sistema X11. Em
 seguida, digite neste mesmo terminal a letra {\tt q} para terminar o top
 e veja o que acontece.

 \item Isto sugere que qualquer programa que rode num terminal de
 caracteres pode ser rodado dentro do sistema X11 através do uso de um
 terminal e de uma operação do tipo que é realizada pelo comando {\tt
 exec}. De fato, o comando {\tt xterm} tem uma opção que permite
 exatamente este tipo de uso.

 Normalmente, quando se executa o {\tt xterm}, uma shell é iniciada dentro
 dele, para que o terminal possa ser usado para a interação com o sistema.
 Verifique isto executando o comando {\tt xterm \&}. Você agora voltou a
 ter duas janelas de terminal disponíveis. Execute agora o comando {\tt
 xterm -e top \&}, em qualquer das duas janelas de terminal. A opção {\tt
 -e <programa>} troca a shell pelo programa discriminado. Verifique que
 aparece mais uma janela de terminal rodando o top dentro. Digite {\tt q}
 nesta nova janela e veja o que acontece.

 \item Você acaba de fabricar um aplicativo X11 a partir de um aplicativo
 para terminais de caracteres, que poderíamos até chamar de {\tt xtop}!
 Com isto, podemos associar a um botão do sistema de janelas qualquer
 comando, mesmo que ele rode apenas em terminais de caracteres.

 \item Saia da sua seção X11. Para isto, de-iconize a janela de terminal
 que apareceu originalmente quando você entrou. Dependendo de como estiver
 configurado o sistema de gerenciamento de janelas você estiver usando, o
 ícone que representa aquela janela pode estar dentro de uma caixa, um
 gerenciador de ícones, ou em qualquer lugar da tela. Nestas notas
 estaremos assumindo que você está usando o gerenciador {\tt fvwm},
 configurado de uma certa forma padronizada.

 Caso o gerenciador de ícones esteja sendo usado, basta clicar uma vez o
 botão esquerdo do mouse em cima do botão que representa a janela. Caso
 contrário, basta dar um double-click, ou seja, clicar rapidamente duas
 vezes com o botão esquerdo do mouse, em cima do ícone que representa a
 janela, o qual pode estar em qualquer lugar da tela.

 Uma vez aberta a janela, execute o comando {\tt exit} nela para terminar
 a sua seção. Sempre que abandonar um terminal, verifique que você fechou
 todas as seções que tiver iniciado nele, tanto no X11 quando nos consoles
 de caracteres, caso contrário sua conta estará aberta e sem proteção, à
 mercê de qualquer um que tenha acesso ao terminal.

\end{enumerate}

\section{Problemas e Dicas}

\begin{enumerate}

 \item Ou outro programa apropriado para a manufatura de um aplicativo X11
 a partir de um aplicativo para terminal de caracteres é o cliente de mail
 {\tt pine}. Este é um programa que você provavelmente já está tentando
 usar, que permite a leitura e o envio de mensagens de email. Tomando como
 guia o exemplo do texto, crie uma linha de comando para rodar um {\tt
 pine} dentro de um terminal {\tt xterm}.

 \item Uma das coisas que deixa os usuários iniciantes confusos em relação
 ao uso do sistema de mail em geral e do {\tt pine} em particular é que,
 em geral, as mensagens de mail são recebidas apenas em uma determinada
 máquina de um conjunto de máquinas que atuam em conjunto numa rede,
 máquina esta que é denominada de servidor de mail. Em nosso caso, o
 servidor de mail é o {\tt socrates.if.usp.br}. O usuário faz um login em
 alguma outra máquina, executa o {\tt pine} e descobre que não há nenhuma
 mensagem recebida. Na realidade, há, mas elas estão no servidor de mail.

 Há formas mais estruturadas de resolver este problema, mas por enquanto
 vamos tentar inventar uma linha de comando que rode o pine sempre na
 máquina correta, mesmo se ele for executada em alguma outra máquina. Para
 isto, tente dar uma olhada no comando {\tt rsh}, que serve para executar
 um comando numa máquina remota. Combine os elementos de tal forma que
 este comando seja executado dentro de um {\tt xterm}, com a consequência
 de que ele subsequentemente execute o {\tt pine} no {\tt socrates}. Esta
 é uma combinação muito útil, que poderíamos no futuro associar a um botão
 do sistema de janelas, criando assim uma forma conveniente de ler o mail.

 \item Você consegue imaginar onde os programas {\tt ps} e {\tt top} vão
 buscar todas as informações que eles nos mostram? Dê uma boa passeada
 pelo filesystem virtual que está montado em {\tt /proc} e dê uma boa
 olhada por lá para ver se dá para compreender a natureza do conteúdo dos
 arquivos que existem lá. Este filesystem virtual é, na realidade, um
 dispositivo através do qual podemos ver (e, às vezes, mudar, desde que se
 tenha autorização de root) as tabelas internas de dados do kernel.

 \item Se você sabe um pouco de programação na linguagem C, escreva um
 pequeno programa chamado {\tt upcase.c} para ler caracteres do canal
 padrão de entrada {\tt stdin} (use para isto a função {\tt getchar()}) e
 escrever caracteres no canal padrão de saída {\tt stdout} (usando a
 função {\tt putchar}), de tal forma que todos os caracteres que
 correspondem às letras sejam transformados em caracteres maiúsculos,
 independentemente de entrarem como minúsculos ou maiúsculos. Não se
 esqueça de incluir a cedilha e todas as letras acentuadas.

 Use este programa numa pipeline junto com os comandos {\tt cat} e {\tt
 more} para transformar em maiúsculas todo o conteúdo do arquivo fonte
 desta apostila ou de algum outro arquivo de texto. Escreva outro programa
 chamado {\tt downcase.c} para fazer o inverso. Se você não sabe nada de C
 mas conhece alguma outra linguagem de programação, use-a, seja ela
 compilada ou interpretada.

\end{enumerate}

\section{Uma Lista de Comandos Relevantes}

\begin{description}\setlength{\itemsep}{0ex}

 \item[\tt bg \%<número-do-job>]: coloca o job de número indicado para
 rodar no background; é um comando built-in da shell.

 \item[\tt cat <arquivo>]: mostra o conteúdo do arquivo.

 \item[\tt exec <programa>]: executa o programa, que passa a substituir a
 shell, a qual termina; é um comando built-in da shell.

 \item[\tt exit]: termina a sessão, ou seja, a shell; é um comando
 built-in da shell.

 \item[\tt fg \%<número-do-job>]: conecta o job de número indicado com o
 terminal; é um comando built-in da shell.

 \item[\tt jobs {[-l]}]: mostra o conjunto de jobs que estão sob a
 administração da shell; com a opção {\tt -l}, mostra também os números
 dos processos (PID) associados aos jobs; os brackets quadrados que se
 colocamos na descrição deste comando são uma forma comum de indicar que o
 que está dentro deles é opcional e não necessário para a execução do
 programa em questão; é um comando built-in da shell.

 \item[\tt kill {[-9]} <número-do-processo>]: elimina o processo cujo
 número (PID) é o indicado; sem a opção {\tt -9} isto é feito enviando um
 sinal de terminação, chamado TERM, para o processo; alguns programas
 podem não entender este sinal e se recusarem a morrer; com a opção {\tt
 -9} é enviado um sinal KILL, que com certeza faz o processo morrer; é um
 comando built-in da shell.

 \item[\tt man <nome-de-comando>]: mostra a página de manual do comando;
 para sair, basta digitar a letra {\tt q} (de ``quit'').

 \item[\tt more <arquivo>]: mostra o conteúdo do arquivo, uma página de
 cada vez; a página tem o tamanho da tela do terminal e passa-se de cada
 página para a próxima digitando-se espaços, ou seja, usando a barra de
 espaço do teclado.

 \item[\tt ps {[a][u][x]}]: mostra processos que estão rodando no sistema;
 sem opções, mostra apenas os processos do usuário que estão conectados a
 um terminal; a opção {\tt a} inclui os processos de outros usuários; a
 opção {\tt u} faz com que o comando mostre o usuário ao qual pertence
 cada processo; a opção {\tt x} inclui os processos que não estejam
 conectados a um terminal.

 \item[\tt top]: monitora os processos do sistema, mostrando os mais
 ativos em ordem decrescente de atividade; trata-se de um aplicativo
 interativo, para sair dele digita-se a letra {\tt q}.

 \item[\tt xclock]: é um aplicativo X11 que abre uma janela contendo um
 relógio.

 \item[\tt xterm {[-e <programa>]}]: é um aplicativo X11 que abre uma
 janela de terminal; em geral uma shell é executada dentro do terminal;
 com a opção {\tt -e <programa>} o programa discriminado é executado em
 lugar da shell.

 \item[\tt ypcat <mapa-do-NIS>]: mostra o conteúdo de uma mapa de dados do
 sistema NIS (Network Information System).

\end{description}

\section{Arquivos de Configuração}

 A shell que usamos como default, a {\tt tcsh}, é controlado por dois
 arquivos de configuração, chamados {\tt .cshrc} e {\tt .login}, na raiz
 da sua conta. Entretanto, relativamente poucas configurações dentro
 destes arquivos dizem respeito diretamente aos assuntos que examinamos
 nesta apostila. Olhe dentro deles ou dos arquivos que são chamados de
 dentro deles com o comando {\tt source} e descubra se há alguma definição
 de {\tt alias} usando pipelines. Você poderia imaginar alguma utilidade
 para um alias deste tipo, que combinasse vários comandos para executar
 operações mais complexas? Tente implementá-lo em sua conta.

 Olhe também os arquivos de configuração do sistema de janelas {\tt fvwm}
 dentro do diretório {\tt .fvwm/} na raiz da sua conta ou, caso ele não
 exista, na raiz de alguma outra conta que esteja aberta para leitura.
 Veja se você pode identificar em algum lugar a encodificação de comandos,
 programas ou pipelines cuja execução esteja associada a botões ou menus.
 Caso ele ainda não exista, crie um diretório chamado {\tt .fvwm/} na raiz
 da sua conta e copie para dentro deles as configurações de algum colega
 ou de qualquer outro usuário do sistema para poder brincar um pouco com
 elas. Lembre-se, é lícito ler e copiar qualquer coisa que esteja aberta
 para leitura, este sistema funciona na base de livre compartilhamento de
 informação.

\end{document}

###

