domingo, 5 de fevereiro de 2012

Standard Input e Standard Output

Amigos leitores vocês sabem o que é Standard Input e Standard Output (ou entrada padrão e saída padrão)? Bom, este post é para aqueles que não sabem e gostariam de saber.

Standard Input (SI) e Standard Output (SO) são respectivamente fluxos de entrada e saída de dados de uma aplicação. Basicamente qualquer aplicação rodando no seu computador tem acesso a estes fluxos de dados, seja ela um programa C compilado ou até mesmo seus scripts PHP. A forma e funcionamento destes fluxos é transparente para os programas já que este trabalho é feito pelo sistema operacional.

O sistema operacional também cuida da origem dos dados passados para a SI. Para um programa rodando na linha de comando geralmente os dados enviados para a SI deste programa vêm do teclado. Já tudo o que o programa escreve na SO o sistema operacional manda para o monitor. Ou seja, um programa que lê da SI e manda a saída para a SO se torna bastante flexível pois desta forma ele pode ser combinado com outros programas e scripts através destas interfaces universais. Este é o princípio da filosofia Unix:
This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface. - Doug McIlroy 
Estas "text streams" citadas são a entrada e saída padrão.

E como fazer isso em PHP? No PHP a forma mais fácil de acessar a SI e SO é usando as constantes STDIN e STDOUT. Estas constantes são do tipo resource, o mesmo tipo retornado por funções como fopen.

Para lermos uma linha de texto digitada pelo usuário juntamente com o caractere "\n" (nova linha) podemos prosseguir da seguinte maneira:
$entrada = fgets(STDIN);

Se quisermos ler somente um caractere, para usar em uma construção switch por exemplo, podemo usar o seguinte código:
$opcao = fgetc(STDIN);

O STDIN é um stream que somente pode ser lido, e o STDOUT é um stream onde é permitido apenas escrever. Nos exemplos abaixo vamos demonstrar o uso do STDOUT.

Aqui vai um exemplo de dois programas que demonstram o poder da filosofia unix de criar programas pequenos que fazem apenas uma coisa bem e conversam com o mundo exterior através das interfaces universais SI e SO. Neste exemplo nós vamos processar o seguinte arquivo csv:

Astolfo,45
Bruna,22
Carlos,63
Daiana,15
Eriberto,30

É uma lista de nomes de pessoas com suas idades. Nós queremos criar um novo arquivo com os nomes em letras maiúsculas e com as idades em dias ao invés de anos. O nosso primeiro programa apenas processa os nomes das pessoas e passa o resultado para a SO permitindo que outros programas possam processar sua saída:



O próximo programa também lê a entrada através da SI, converte as idades de anos para dias e manda o resultado para SO.



Veja que os programas são praticamente iguais na forma como leem a entrada e escrevem na saída. Se você estiver em sistema *nix os seguintes comandos na linha de comando podem ser usados para lermos o arquivo original, usarmos os dois programas para processá-lo e criar um novo arquivo com a saída. Considerando-se que os scripts php e arquivo csv estão no mesmo diretório:

php capitalize_names.php < listanomes.csv | php ages_in_days.php > listanomes-saida.csv

Veja que estamos invocando o php para executar os scripts. Mas o que estes símbolos de menor, maior e tubo (|) estão fazendo ali?

Estes símbolos tem grande importância na execução dos programas.

  • <: Ele serve para redirecionarmos a Standard Input do script capitalize_names.php. No comando acima estamos dizendo para o sistema operacional que quando o script começar a ler o que estiver na SI ele mande o que estiver no arquivo listanomes.csv ao invés de mandar o que o usuário digitar no teclado.
  • >: Ele tem o mesmo propósito de redirecionamento do símbolo anterior. Só que agora estamos redirecionando a Standard Output. No comando acima estamos dizendo para o sistema operacional para que seja lá que o script age_in_days.php escrever em sua SO ele mande para um arquivo chamado listanomes-saida.csv, e o sistema operacional cuida da criação do arquivo caso ele não exista.
  • |: O tubo ou pipe como é chamado no mundo Unix é usado no comando acima para mandarmos a Standard Output do script capitalize_names.php para a Standard Input do script age_in_days.php.
No nosso exemplo acima usamos dois programas pequenos que nós mesmos criamos mas poderíamos ter usado muitos outros programas presentes no sistema operacional como grep, cat, wc etc.

O uso de redirecionamento da SI e SO juntamente com o uso de pipes é um recurso muito poderoso e bastante utilizado. Espero que com este post vocês possam assimilar este poder nos seus scripts PHP criar aplicações valiosas. Até a próxima!

Nenhum comentário:

Postar um comentário