3

次のサンプル スクリプトを検討してください。

<?php

$pipes = array();
$p = proc_open('cat', array(0 => STDIN, 1 => STDOUT, 2 => STDERR), $pipes);
fgetc(STDIN);

(Debian のデフォルト) に/bin/shシンボリック リンクされている場合、シェルで実行されます。/bin/dashcat

30760 pts/0    S+     0:00  |           \_ php f.php
30761 pts/0    S+     0:00  |               \_ sh -c cat
30762 pts/0    S+     0:00  |                   \_ cat

ただし、/bin/shがリンクされている場合は、 の直接の子です:/bin/bashcatphp

30786 pts/0    S+     0:00  |           \_ php f.php
30787 pts/0    S+     0:00  |               \_ cat

これは、生成されたプロセスにシグナルを確実に送信することを不可能にする非常に厄介な矛盾です (シグナルはシェルによって受信される場合があるため)。

proc_open/bin/shが指す場所によって動作が異なるのはなぜですか? シェルを実行しない方法/bin/shはありbashますか?

4

1 に答える 1

4

どちらの場合も、PHP は /bin/sh 経由でコマンドを実行します。違いは、PHP ではなくシェルにあります。dash はプロセスを fork してコマンド (この場合は cat) を実行し、コマンドが終了するのを待ちます。bash は execve() を実行するため、独自のプロセスを cat に置き換えます。

ただし、後のバージョンでは修正されているようです: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=436466

実行されたコマンドは生成されたシェルの PID を取得し、シグナルを受信するため、bash または最新バージョンのダッシュを使用すると問題が解決するはずです。</p>

于 2014-03-28T11:13:15.187 に答える