在 PHP 腳本中執行系統 bash 指令 - 語法錯誤:意外的 T_LNUMBER

在 PHP 腳本中執行系統 bash 指令 - 語法錯誤:意外的 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 變數。但是您在 shell 腳本中使用它,它將由 shell 解析。根據您所編寫的內容,假設該變數的內容是$(tar czf /proc/$PPID/fd/1 /var/mysql) admin down- 那麼伺服器將愉快地提供資料庫轉儲(這個確切的命令可能會也可能不會工作,具體取決於 PHP 腳本的使用方式,但我希望您明白)。

要解決最後一個問題(這是最複雜的問題),您可以透過環境傳遞變數來避免引用麻煩。環境變數被 shell 視為 shell 變數。

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}\'');

如果要將字串傳遞到 shell 腳本中,則需要為 shell 正確引用它。最簡單的方法是使其成為單引號文字;這需要轉換字串內的單引號。

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

為什麼你要先呼叫 shell 腳本? PHP 擁有執行此類簡單文字操作所需的一切。呼叫 shell 腳本不僅很奇怪,而且非常脆弱(正如這個答案所示);你肯定會弄錯,所以不要這樣做。

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

(請注意,我可能沒有完全寫出您想要的內容,因為1.您的awk代碼很奇怪(為什麼在開頭保留一些空格?)以及2.我不懂PHP。)

在您了解自己在做什麼之前,請勿將此程式碼投入生產。一旦最緊迫的語法錯誤得到修正,您的程式碼就會充滿安全漏洞(您允許$line使用任意 shell 指令 — 沒有比這更容易被利用的了)。在徹底的安全審查之前,請勿允許此程式碼在您的(希望有防火牆的)測試機器之外執行。

答案2

嘗試使用單引號而不是雙引號

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

單引號幾乎總是「按原樣」顯示內容。更多詳情你可以找到在官方文件中

相關內容