次は私がPHPで書いたがbash
。awk
私は文字列の4番目または5番目の要素(に格納されている$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とシステムの機能に関する専門知識が欠けているので、問題の原因が正確に何であるかわかりません。誰でもこれを説明できますか?この問題を調べてみましたが、このエラーは非常に一般的で、Web上の多くの問題がawk
人々がPHPスクリプトの代わりにCLIで実行するシナリオの一部であるため、私の状況はユニークです。
以下は変数のデータ例です$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}'"
ここには多くの問題があります。
- これは2つの並列文字列リテラル
"echo \"$line\" | awk '{$1=$2=$3=$4="
です"; print $0}'"
。これは有効なPHP構文ではありません。バックスラッシュを使用してこれら2つの二重引用符を保護する必要があります。 $
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コードが奇妙なので(なぜ最初にスペースを残すのですか?)
実行している作業を理解するまで、このコードを本番環境に適用しないでください。最も緊急の構文エラーが修正されると、コードはセキュリティホールに満ちています(任意の$line
シェルコマンドを使用できるようにします。これより悪用しやすいものはありません)。徹底的なセキュリティレビューを進める前に、このコードが(ファイアウォール付き)テストシステムの外部で実行されることを許可しないでください。