Shell Script em PHP II

Neste artigo vamos construir uma pequena aplicação do zero utilizando o PHP Scripting. A idéia é preparar o terreno para quando começar a lançar os artigos para trabalho com o PHP-GTK.

Neste artigo iremos um pouco mais a fundo nas variáveis argc e argv contidas no PHP, quando estamos trabalhando com o mesmo para criação de Shell Scripts e por sua vez, talvez um comando shell qualquer.
Demorou, mas achei que já havia chegado a hora de trabalhar um pouco mais com o tema PHP Scripting no mundo SHELL. O PHP se mostrou nos últimos tempos uma linguagem altamente divertida para criação de diversos tipos de Shell Scritpt.

A Barra Brasil contida no meu site, uma idéia do site BR-Linux, foi criada é criada a partir de um shell script php que gera um arquivo estático com os links, a cada uma hora ( logicamente, nesta solução foi aplicado o cron do sistema operacional ).

Assim, achei legal trabalhar na prática para criar um comando, pois o primeiro artigo foi uma pincelada bem generalizada no assunto. Assim, vamos aplicar o que vimos no primeiro artigo, em um segundo, agora preocupando com a profissionalização de um comando, ou seja, torná-lo mais aplicável em ambientes práticos.

Veja, uma das primeiras coisas que devemos preocupar quando vamos criar um comando é a localização do interpretador. Quando digitamos :

php comando.php

Estamos por sua vez chamando o interpretador de comandos, e ele a partir daí passa a interpretar e executar o seu código. Mas, torna-se meio inviável, se criar um alias no shell de cada usuário para quando ele digitar comando, o shell chamar o php comando.php.

Portanto, uma das primeiras coisas que devemos no preocupar quando criamos um comando em php, é a localização do interpretador. O Unix fornece vários modos de se encontrar o interpretador. Um exemplo generalizado dos modos que você pode encontrar o interpretador :

bash-3.00$ type php php is /usr/bin/php bash-3.00$ whereis php php: /usr/bin/php /usr/lib/php /usr/local/lib/php /usr/include/php /usr/man/man1/php.1.gz /usr/share/man/man1/php.1.gz

Ou seja, em todos os exemplos, é possível saber que o seu interpretador se encontra em /usr/bin/php. Assim, a primeira linha do seu script shell PHP tem que ser a famosa linha que chama o interpretador.

Quem já mexeu com shell, perl, python, vai entender de cara a linha. Veja abaixo :

#!/usr/bin/php

O que significa esta linha ? Bom, esta linha literalmente vai chamar o interpretador, e ele vai executar todos os comandos dele contidos no arquivo. Lembrar que, mesmo sendo um script shell em PHP, você deve usar as tags <?php ?> para que o seu programa não sofra nenhum problema de execução.

Porque resolvi lembrar isto aqui ? Porque neste artigo, esta citação que fiz no primeiro artigo, vai ter que ser muito melhor lembrada :-) Mas vamos continando.

Com base no seu interpretador de comandos, temos agora também que lembrar uma coisa. Um arquivo executável no mundo Unix, pode ser um arquivo texto, que contém comandos internamente a serem executados. O que mostra para o sistema operacional o que deve ou não ser executado, são as permissões.

Veja, se você digita o comando ls no seu shell, ele é executado. Isto acontece, pois o binário do comando contém permissões de execução. É aí que entra a importância das permissões quando falamos de um script shell php que tem a intenção de ser um comando de sistema operacional.

Portanto, o script que você criar deve possuir permissão de execução. Esta permissão de execução, no mundo Unix, é fornecida através do comando chmod. No nosso caso devemos no preocupar em como fornecer a permissão de execução, que é feita com a seguinte sintaxe do comando chmod :

chmod 755 arquivo

Para ir mais a fundo, sobre as permissões de execução, aconselho uma leitura no ótimo tutorial que o Meleu ( aliás, gostaria de saber qual a url do site do Meleu, pois o antigo do hpg desapareceu ) escreveu a um tempo atrás, sobre permissão em Unix.

Para ir mais a fundo, sobre as permissões de execução, aconselho uma leitura no ótimo tutorial que o Meleu escreveu a um tempo atrás, sobre permissão em Unix.

A partir disto, podemos começar a pensar em nosso pequeno script. O exemplo que iremos utilizar neste tutorial, será um script que irá criar diretórios. Ou seja, um comando mkdir bem simplificado.

Quando digitamos um comando em um prompt, e ele necessita de alguma outra opção, ele automaticamente, irá lhe mostrar um help.

bash-3.00# whereis whereis [ -sbmu ] [ -SBM dir … -f ] nome…

Em geral, os comandos no mundo Unix, são programas escritos em C. O C possui duas variáveis extremamente importantes quando estamos criando comandos para o mundo console.

São elas argc e argv. A variável argv já foi citada no primeiro artigo, portanto não vai ser citada novamente aqui, pois não faz sentido.

Mas quem é esta tal variável argc ? O argc contém o número de argumentos da linha de comando.

Com um exemplo prático vai ser mais fácil entender aonde queremos chegar.

#!/usr/bin/php -q <?php

    print(“Você digitou $argc argumentos no consolen”);

?>

Salve o arquivo como teste1.php e vamos agora brincar testá-lo.

chmod 755 teste1.php

bash-3.00$ ./teste1.php php Você digitou 2 argumentos no console

bash-3.00$ ./teste1.php php eh Você digitou 3 argumentos no console

bash-3.00$ ./teste1.php php eh bom Você digitou 4 argumentos no console

Ou seja, o argc sempre vai listar o número de argumentos digitados no console. Mas possivelmente deve ter ficado uma dúvida. Porque diabos ele sempre coloca um argumento a mais ? Se eu digitei 3 argumentos porque ele lista 4 ?

Novamente vamos resolver a sua dúvida com um código PHP :-)

#!/usr/bin/php -q <?php

    print(“Você digitou $argc argumentos no consolen”);    for($i = 0; $i < 4; $i++)      print(“argv[$i] = “.$argv{$i]. “n”;

?>

bash-3.00$ ./teste2.php php eh bom

Você digitou 4 argumentos no console argv[0] = ./teste2.php argv[1] = php argv[2] = eh argv[3] = bom

Ou seja, o primeiro argumento é sempre o próprio comando digitado. Assim, se queremos forçar sempre o usuário a digitar um argumento no console, simplesmente temos que fazer um teste onde argc nunca deve ser menor que dois. E, sempre que for necessário um número x de argumentos, coloque este número de argumentos no seu mkdir :-)

Bom, então vamos testar com o nosso comando, aumentando um teste de número de argumentos digitados.

#!/usr/bin/php -q <?php

    print(“Você digitou $argc argumentos no consolen”);    if($argc < 2)     {      print(“É necessário digitar um argumenton”);      return;     }    for($i = 0; $i < 4; $i++)      print(“argv[$i] = “.$argv{$i]. “n”;

?>

bash-3.00$ ./teste3.php

Você digitou 1 argumentos no console É necessário digitar um argumento

bash-3.00$ ./teste3.php php eh bom

Você digitou 4 argumentos no console argv[0] = ./teste3.php argv[1] = php argv[2] = eh argv[3] = bom

Ou seja, com este teste você força o usuário a digitar um comando. Agora, sim, após entender estes conceitos vamos passar a construção do nosso comando mkdir.

Bem, para a construção do nosso comando mkdir, iremos usar o comando mkdir que o próprio PHP possui. Legal, não é ? Lembrar que este é um script de mkdir simples, que logicamente não vai cobrir tudo que um mkdir precisa :-)

Iremos agora navegar pelo código, nas partes realmente importantes, para entendermos como ele foi construido, e como você pode construir scripts úteis paro seu dia a dia em PHP. Você pode efetuar o download do código completo aqui.

9   function MakeDirectory($dir, $mode = 0755) 10   { 11    if (is_dir($dir) || @mkdir($dir,$mode)) return TRUE; 12    if (!MakeDirectory(dirname($dir),$mode)) return FALSE; 13    return @mkdir($dir,$mode); 14   }

Esta função eu peguei na explicação sobre a função mkdir no site oficial do PHP, onde a intenção desta função é ser recursiva por ela mesma, pois caso você mande diretório completo, ele vai chamar a função recursivamente, até ela criar o diretório por completo. Mas como pensei em algo um pouco diferente, somente a usei por ter proteções que eu não queria ter que implementar no código.

15  function CreatingDirs($tmpcaminho,$tipo) 16   { 17
18    $caminho = explode("/",$tmpcaminho); 19
20    if($tipo == “naolocal”) 21     $dirtocreate = “/"; 22
23    if(count($caminho) > 2) 24     { 25      foreach($caminho as $local) 26       { 27        $dirtocreate = $dirtocreate.$local."/"; 28        if(MakeDirectory($dirtocreate)) 29         $feito = TRUE; 30       }
31   } 32    else 33     { 34      if(MakeDirectory($caminho[0])) 35       $feito = TRUE; 36
37     }
38
39    return $feito; 40
41   }

A função CretingDirs é a mais importante do script. É ela que vai fazer todo o trabalho de decomposição do caminho do diretório + criação do diretório. Ou seja, se for um caminho enorme, ele mesmo cria todo o caminho, sem excessão, e fazendo os testes necessário, devido a função MakeDirectory.

Na linha 18 o caminho digitado pelo usuário é decomposto usando a função explode. Esta função decompõe o arquivo de acordo com a string de controle. Assim, ele cria um array em que cada elemento é um dos diretório a ser criados. Se o diretório é não local, ele recebe $dirtocreate recebe o local, mais a string que está já adicionada no código.

Logo após é chamada a função MakeDirectory que está em um if. Se ela retornar TRUE, que é a criação do diretório, a variável feito recebe o valor TRUE, se não, ela recebe FALSE.

Isto acontece também no else, pois, se for um diretório único, a função MakeDirectory é chamada dentro de um if e retorna a variável $feito.

49  $caminho = $argv[1]; 50 51  if($caminho[0] == “/") 52   { 53    $feito = CreatingDirs($caminho,“naolocal”); 54   } 55  else 56   { 57    $feito = CreatingDirs($caminho,“local”); 58   }

Aqui são feitos testes necessários para falar se o diretório é de tipo não local, ou seja, um diretório que começa com o caminho / ou então, um diretório local, que começa sem a barra.

Ou seja, como pode ser visto, com um pouco de criatividade, você pode criar comandos muito interessantes com o PHP. Ele, tal qual outras linguagens de script, fornece uma gama enorme de funções que pode lhe ajudar e muito, nas suas tarefas do dia a dia.