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 awk
funçã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 awk
problemas 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 $line
variá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
line
variá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 $line
ser 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