O diretório /proc
Os processos são tão fundamentais e importantes no sistema, que existe este diretório, que guarda todas as informações dos processos que estão rodando, além de informações do sistema operacional, dos dispositivos USB conectados e algumas informações do hardware.
Acessando tal diretório, você irá notar que cada processo possui seu próprio diretório, cujo nome é a PID do processo:
ls /proc
Na verdade, ele não é bem um diretório, é um sistema de arquivos (File System) virtual, onde o kernel traça as estruturas de dados interna do kernel para que pareçam arquivos e diretórios, pois sendo vistos como tais, são mais úteis, já que a maior parte dos comandos (do Unix, na verdade) trabalham com arquivos.
Vamos explorar algum destes diretórios, como o 14297 (no meu), através do
ls com flags que mostram mais informações de cada arquivo:
ls -CFl /proc/14297/fd
fd é de file descriptors, que falamos no artigo de
Pipelines, (0 para stdin, 1 para stdout e 2 para stderr, por exemplo), que são mostrados antes do '->', além de sockets, pipes e outras informações daquele processo.
Dentro de cada processo existe uma série de arquivos interessantes, como o
environ. Usando o comando
cat, para olhar o conteúdo desse arquivo, você verá que ele, aparentemente, está todo desorganizado, além de possuir caracteres não visíveis.
Use o seguinte comando para ver melhor o conteúdo:
od -a /proc/14297/environ
Note que as variáveis estão separadas por um caractere
nul (ASCII 0) ou '\000', cuja interpretação só é 'vista' pela máquina.
Vamos usar o comando
tr (de "translate"), para transformar esse caractere em nossa quebra de linha, visível, '\n':
tr "\000" "\n" < /proc/14297/environ
Agora é possível ver as variáveis do processo.
Iniciando (launching) e matando (killing) processos
Não é somente dar um comando para rodar o processo.
Há várias formas sobre como rodar o processo, como por exemplo, em background, foreground, em um subshell, invocando
exec (não retorna para seu script) ou em
fork (criando processos filho).
Foreground
Para rodar em foreground, ou primeiro plano, não tem segredo. Basta rodar o comando normalmente, como sempre fazemos. Aqui é só nomenclatura, só pra você saber que o nome disso é foreground. ;)
Background
Você roda em primeiro plano (foreground) porque também pode rodar em segundo plano (background).
Para rodar em background, usar o caractere ampersand '&', também conhecido como 'e comercial' ou sinal tironiano (VOL também é cultura), ao final de seu comando, como você já deve ter percebido no script inicial desse artigo.
O uso do '&' não funcionará bem, porém, se você usar com comandos que enviam a saída para a
stdout (redirecione), em comandos que precisem de entrada fornecida pelo stdin (redirecione), ou caso seus scripts interajam com o comando.
Subshell
Um subshell é uma espécie de 'filho' ou instância do shell 'atual'.
Você pode usar para rodar um processo em paralelo, por exemplo, ao passo que faz um processo no shell principal e usar o resultado de um no outro.
Quando rodamos um script, por exemplo, ele é executado em um subshell.
Para rodar um comando em um subshell, simplesmente envolva tal comando entre parêntesis. Veja por si só:
echo "Atual: $BASH_SUBSHELL" ; (echo "Subshell: $BASH_SUBSHELL")
exec
Caso não queira um comando em um subshell, use o comando
exec antes dos outros comandos, que ele irá forçar o comando a ser rodado na instância atual do shell.
Exemplo:
exec echo "Alguém me lê?"
Porém, o 'exec' é mais útil na forma de script.
Crie o script 'exec':
exec echo "Olá, agora você me lê"
echo "Forever alone"
Executando:
sh exec
Nota-se que somente o primeiro 'echo' é exibido.
Tenha sempre em mente que, com o 'exec', a coisa vai, mas não volta.
Ele substitui o antigo processo pelo novo, ou seja, seu script termina. Cuidado para não perder suas informações. Sempre que usar, certifique-se de que não precisará mais de nada do script.
Ele é particularmente útil para liberar recursos do seu script, como memória, sendo usado em scripts mais longos e consumidores de recursos.
Killing (matando um processo)
Podemos parar a execução de um processo que desejarmos (geralmente por ter travado, por não ter sido finalizado de maneira correta ou ainda estar rodando por algum motivo obscuro), chamamos carinhosamente isso de 'kill'.
Na verdade, o comando não mata nada. Ele simplesmente envia um sinal para o processo, que decide se termina normalmente ou comete 'suicídio' (a maioria dos comandos são programados para se matarem ao receberem um sinal).
Para finalizarmos um processo, usamos o comando
kill e a ID do processo. Usamos a opção '-9' pra enviar o SIGKILL.
Por exemplo, vi que a PID do player
Clementine é 30271. Para fechá-lo:
kill -9 30271
Obviamente se estiver tocando Rush no seu player, você irá fechar outro aplicativo que não seja o Clementine.
Caso não seja root, você precisa ter sido a pessoa a ter rodado aquele programa.
Caso
exit no terminal não seja o suficiente para sua sede de Unix, e você queira sair em grande estilo:
kill -9 $$
Os comandos para matar algum processo são vários e nem todos enviam sinais.
Como o objetivo deste artigo é somente apresentar as ferramentas e informações existentes à respeito dos processos, não irei entrar em detalhes.
Caso precise saber mais (ou através dos artigos aqui mesmo do VOL):
man kill
(but woman kills more)