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

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

Abaixo está um extrato de um script que 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 awkfunção ideal no cenário que me foi apresentado. Estou tentando obter o quarto ou quinto elemento de uma string (armazenada em $line), com a qual pretendo trabalhar. Porém, sempre que o executo com o código abaixo me é apresentado 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, devido à minha falta de experiência com PHP e com a função do sistema, não tenho certeza do que exatamente está causando o meu problema. Alguém pode lançar alguma luz sobre isso? Tentei pesquisar o problema, porém o erro é bastante genérico e minha situação é bastante única, pois muitos dos awkproblemas na web fazem parte de um cenário em que a pessoa o está executando a partir da CLI e não de um script PHP.

Aqui está um exemplo de quais dados estariam na $linevariável:

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;
   }
}

Responder1

Você tem este trecho em um script PHP:

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

Existem muitos problemas com isso:

  • Esses 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 entre aspas duplas é expandida por PHP. Você precisa \$evitar isso.
  • Sua linevariável é uma variável PHP contendo uma string. Mas você o 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 dump do banco de dados (esse comando exato pode ou não funcionar dependendo de como o script PHP é usado, mas espero que você tenha entendido ).

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

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

Como alternativa, use aspas simples em PHP, que exigem a citação apenas de \e '.

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

Se você deseja passar uma string para um script de shell, 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.

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

Maspor 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 essas. Chamar um script de shell não é apenas estranho, é extremamente frágil (como mostra esta resposta); você está fadado a errar, então não faça isso.

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

(Observe que posso não ter escrito exatamente o que você queria, porque 1. seu código awk é estranho (por que você está mantendo alguns espaços no início?) e 2. não conheço PHP.)

Não coloque esse código em produção até entender o que está fazendo. Depois que os erros de sintaxe mais urgentes são corrigidos, você tem um código repleto de falhas de segurança (você permite $lineser um comando shell arbitrário - não existe nada mais fácil de explorar do que isso). Não permita que este código seja executado fora de sua máquina de teste (esperamos que esteja com firewall) até que ela tenha passado por uma revisão de segurança completa.

Responder2

Tente usar aspas simples em vez de aspas duplas

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

Aspas simples exibirão as coisas quase sempre "como estão". Mais detalhes você pode encontrarna documentação oficial

informação relacionada