Executando o comando bash do sistema no script PHP - erro de sintaxe: inesperado T_LNUMBER

1

Abaixo está uma extração de um script que eu escrevi em PHP, mas contém um comando do sistema que é executado em bash . Agora, a razão para isso é porque me permite usar a função awk , que é ideal no cenário que me foi apresentado. Estou tentando obter o quarto ou quinto elemento de uma string (armazenado em $line ), com o qual planejo trabalhar. No entanto, sempre que eu o executar com o código abaixo, recebo o seguinte erro:

PHP Parse error:  syntax error, unexpected T_LNUMBER, expecting T_VARIABLE or '$' in /home/hugh/HughScripts/ParseOutputForFieldsV2.php on line 16

A linha 16 é meu primeiro comando do sistema:

system("echo \"$line\" | awk '{$1=$2=$3=$4=""; print $0}'");

No entanto, não tenho certeza, devido à minha falta de conhecimento sobre o PHP e a função do sistema, o que exatamente está causando meu problema. Alguém pode lançar alguma luz sobre isso? Eu tentei pesquisar o problema, no entanto, o erro é bastante genérico e minha situação é bastante singular, como muitos dos problemas awk na web fazem parte do cenário em que a pessoa está executando a partir do CLI ao invés de um PHP roteiro.

Veja um exemplo de quais dados estariam na variável $line :

GiX/X         down           down     CUSTOMER: NX/XXXXXXX : 1Mbps - Offshore SLA

Código abaixo:

$skipFirstLine = 1;

foreach($outputFile as &$line)
{
   if($skipFirstLine == 0)
   {
     if(strpos($line, 'admin down'))
     {
        system("echo \"$line\" | awk '{$1=$2=$3=$4=""; print $0}'");
     }
     else
     {
       system("echo \"$line\" | awk '{$1=$2=$3=""; print $0}'");
     }
   }
   else
   {
     $skipFirstLine = 0;
   }
}
    
por Hugh 18.06.2014 / 13:29

2 respostas

1

Você tem esse snippet em um script PHP:

"echo \"$line\" | awk '{$1=$2=$3=$4=""; print $0}'"

Existem muitos problemas com isso:

  • Estes são dois literais de string justapostos, "echo \"$line\" | awk '{$1=$2=$3=$4=" e "; print $0}'" . Esta não é uma sintaxe PHP válida. Você precisa proteger essas duas aspas duplas com uma barra invertida.
  • $ em uma string PHP com aspas duplas é expandida pelo PHP. Você precisa de \$ para evitar isso.
  • Sua variável line é uma variável do PHP que contém uma string. Mas você está usando dentro de um script de shell, onde será analisado pelo shell. Com o que você escreveu, suponha que o conteúdo desta variável seja $(tar czf /proc/$PPID/fd/1 /var/mysql) admin down - então o servidor servirá alegremente um despejo de banco de dados (este comando exato pode ou não funcionar dependendo de como o script PHP é usado, mas espero que você começa a idéia).

Para resolver o último problema, que é o mais complexo, você pode evitar problemas de cotação passando a variável pelo ambiente. As variáveis de ambiente são vistas pelo shell como variáveis do shell.

putenv("PHP_line=$line");
system("echo \"\$PHP_line\" | awk '{\=\=\=\=\"\"; print \
system('echo "$PHP_line" | awk \'{$1=$2=$3=$4=""; print $0}\'');
}'");

Como alternativa, use aspas simples no PHP, que requerem apenas aspas de \ e ' .

$quoted_line = str_replace("'", "'\''", $line);
system('echo \'' . $quoted_line . '\' | awk \'{$1=$2=$3=$4=""; print $0}\'');

Se você quiser passar uma string para um shell script, você precisa citá-la corretamente para o shell. A maneira mais fácil de fazer isso é torná-lo um literal entre aspas simples; isso requer a transformação das aspas simples dentro da string.

print(preg_replace('/^[\s]*[\S]+[\s]*[\S]+[\s]*[\S]+[\s]*[\S]+/', '    ', $line));

Mas por que você está chamando um script de shell em primeiro lugar ? PHP tem tudo que você precisa para realizar manipulações de texto simples como estas. Chamar um shell script não é apenas estranho, é extremamente frágil (como essa resposta mostra); você está fadado a errar, então não faça isso.

"echo \"$line\" | awk '{$1=$2=$3=$4=""; print $0}'"

(Note que eu posso não ter escrito exatamente o que você queria, porque 1. seu código awk é estranho (por que você está retendo alguns espaços no começo?) e 2. Eu não sei PHP.)

Não coloque este código em produção até que você entenda o que está fazendo. Uma vez que os erros de sintaxe mais urgentes são corrigidos, você tem código montado com falhas de segurança (você permite que $line seja um comando shell arbitrário - não é mais fácil explorá-lo). Não permita que este código seja executado fora de sua máquina de teste (com firewall) até que tenha sido submetido a uma revisão de segurança completa.

    
por 19.06.2014 / 03:37
0

Tente usar aspas simples em vez de qoutes duplos

system('echo "' . $line . '" | awk \'{$1=$2=$3=""; print $0}\''); 

As aspas simples exibirão as coisas quase sempre "no estado em que se encontram". Mais detalhes você pode encontrar na documentação oficial

    
por 18.06.2014 / 14:42