Выполнение системной команды bash в скрипте PHP — синтаксическая ошибка: неожиданный T_LNUMBER

Выполнение системной команды bash в скрипте PHP — синтаксическая ошибка: неожиданный T_LNUMBER

Ниже приведен отрывок из скрипта, который я написал на PHP, но содержит системную команду, которая выполняется в bash. Причина этого в том, что это позволяет мне использовать функцию awk, которая идеально подходит для представленного мне сценария. Я пытаюсь получить четвертый или пятый элемент строки (хранящейся в $line), с которым я затем планирую работать. Однако всякий раз, когда я выполняю его с помощью кода ниже, я получаю следующую ошибку:

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

Строка 16 — моя первая системная команда:

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

Однако я не уверен из-за отсутствия у меня знаний как с PHP, так и с системной функцией, что именно вызывает мою проблему. Может ли кто-нибудь пролить свет на это? Я пытался исследовать проблему, однако ошибка довольно общая, а моя ситуация довольно уникальна, поскольку многие awkпроблемы в Интернете являются частью сценария, когда человек выполняет ее из CLI, а не из скрипта PHP.

Вот пример того, какие данные будут в $lineпеременной:

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

Код ниже:

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

решение1

У вас есть этот фрагмент в PHP-скрипте:

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

С этим связано много проблем:

  • Это два расположенных рядом строковых литерала, "echo \"$line\" | awk '{$1=$2=$3=$4="и "; print $0}'". Это недопустимый синтаксис PHP. Вам нужно защитить эти две двойные кавычки обратной косой чертой.
  • $в двойных кавычках PHP строка расширяется PHP. Вам нужно \$этого избегать.
  • Ваша lineпеременная — это переменная PHP, содержащая строку. Но вы используете ее внутри скрипта оболочки, где она будет проанализирована оболочкой. С тем, что вы написали, предположим, что содержимое этой переменной — $(tar czf /proc/$PPID/fd/1 /var/mysql) admin downтогда сервер с радостью выдаст дамп базы данных (эта точная команда может работать или не работать в зависимости от того, как используется скрипт PHP, но я надеюсь, вы поняли идею).

Чтобы решить последнюю проблему, которая является наиболее сложной, вы можете избежать проблем с кавычками, передавая переменную через окружение. Переменные окружения воспринимаются оболочкой как переменные оболочки.

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

В качестве альтернативы используйте одинарные кавычки в PHP, которые требуют заключения в кавычки только \и '.

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

Если вы хотите передать строку в скрипт оболочки, вам нужно правильно заключить ее в кавычки для оболочки. Самый простой способ сделать это — сделать ее литералом в одинарных кавычках; для этого требуется преобразовать одинарные кавычки внутри строки.

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

Нопочему вы вообще вызываете скрипт оболочки?? В PHP есть все необходимое для выполнения простых текстовых манипуляций, подобных этим. Вызов скрипта оболочки не только странен, но и чрезвычайно уязвим (как показывает этот ответ); вы обязательно ошибетесь, так что не делайте этого.

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

(Обратите внимание, что я, возможно, написал не совсем то, что вы хотели, потому что 1. ваш код awk странный (зачем вы оставляете несколько пробелов в начале?) и 2. я не знаю PHP.)

Не запускайте этот код в производство, пока не поймете, что делаете. После исправления самых серьезных синтаксических ошибок у вас будет код, полный дыр в безопасности (вы позволяете $lineиспользовать произвольную команду оболочки — эксплуатировать ее проще простого). Не допускайте выполнения этого кода за пределами вашей (надеюсь, защищенной брандмауэром) тестовой машины, пока он не пройдет тщательную проверку безопасности.

решение2

Попробуйте использовать одинарные кавычки вместо двойных.

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

Одинарные кавычки почти всегда будут отображать вещи "как есть". Более подробную информацию вы можете найтив официальной документации

Связанный контент