Sim, os processos herdam os descritores de arquivos de seus pais, quando você faz isso:
Em
php -r 'passthru("nano");'
php herdará o stdin do shell (um dispositivo tty se invocado no prompt de um shell interativo) e nano também o herdará (enquanto stdout é um canal usado por php para recuperar o shell saída de nano e passá-lo, nano parece estar feliz com isso, nem todos os editores, você pode querer usar system() aqui).
Em:
something | php -r 'passthru("nano");'
Você está chamando php com stdin agora um pipe com stdout de something na outra extremidade. E nano herdará isso.
Se você quiser que o stdin de php seja o canal, enquanto que nano stdin seja qual for o stdin do shell, você precisará passar esse recurso para php e ter php (ou o shell executado por passthru ) torná-lo o stdin de nano . Isso poderia ser feito com, por exemplo:
{ something 3<&- | php -r 'passthru("nano <&3 3<&-");'; } 3<&0
Quando disponibilizamos o recurso em fd 0 (stdin) no fd 3 dentro de um grupo de comando ( {...;} ), feche-o para something , que não precisa dele ( 3<&- ), e diga o shell é executado pelo passthru do php para restaurar o stdin daquele fd3.
Exemplo:
$ php -r 'passthru("ls -l /proc/self/fd");'
total 0
lrwx------ 1 stephane stephane 64 Mar 19 15:12 0 -> /dev/pts/38
l-wx------ 1 stephane stephane 64 Mar 19 15:12 1 -> pipe:[22538485]
lrwx------ 1 stephane stephane 64 Mar 19 15:12 2 -> /dev/pts/38
fd 0 é um dispositivo tty para interação terminal.
$ echo hello | php -r 'passthru("ls -l /proc/self/fd");'
total 0
lr-x------ 1 stephane stephane 64 Mar 19 15:12 0 -> pipe:[22539326]
l-wx------ 1 stephane stephane 64 Mar 19 15:12 1 -> pipe:[22530020]
lrwx------ 1 stephane stephane 64 Mar 19 15:12 2 -> /dev/pts/38
Agora, o stdin de ls é um canal (o que a echo está alimentando).
$ { echo hello 3<&- | php -r 'passthru("ls -l /proc/\$PPID/fd /proc/self/fd <&3 3<&-");';} 3<&0
/proc/9202/fd:
total 0
lr-x------ 1 stephane stephane 64 Mar 19 15:17 0 -> pipe:[22544619]
lrwx------ 1 stephane stephane 64 Mar 19 15:17 1 -> /dev/pts/38
lrwx------ 1 stephane stephane 64 Mar 19 15:17 2 -> /dev/pts/38
lrwx------ 1 stephane stephane 64 Mar 19 15:17 3 -> /dev/pts/38
lr-x------ 1 stephane stephane 64 Mar 19 15:17 4 -> pipe:[22544623]
/proc/self/fd:
total 0
lrwx------ 1 stephane stephane 64 Mar 19 15:17 0 -> /dev/pts/38
l-wx------ 1 stephane stephane 64 Mar 19 15:17 1 -> pipe:[22544623]
lrwx------ 1 stephane stephane 64 Mar 19 15:17 2 -> /dev/pts/38
O stdin de ls foi feito novamente no dispositivo tty, enquanto seu pai (php) ainda tem o pipe em stdin (veja também o tty em fd 3 e outro pipe em fd 4, provavelmente o que está lendo a saída de ls com).
Então, aqui, você precisa alterar seu script php para:
<?php
foreach(file("php://stdin") as $name) {
echo "Hello $name";
passthru("nano <&3 3<&-");
}
?>
E chame como:
{ printf '%s\n' World Everybody | php script.php; } 3<&0
Para passar os dois recursos (o canal de printf e o stdin original) para php .
Se você espera que o script php sempre seja chamado de dentro de um terminal e que nano sempre deve interagir com o terminal (mas, novamente, observe que php faz seu stdout não o terminal), você pode alterá-lo para:
<?php
foreach(file("php://stdin") as $name) {
echo "Hello $name";
passthru("nano < /dev/tty");
}
?>
Onde codificamos o stdin de nano para ser o terminal de controle.