Да, процессы наследуют файловые дескрипторы своего родителя, когда вы это делаете:
В
php -r 'passthru("nano");'
php
унаследует стандартный ввод оболочки (устройство tty, если оно вызывается по приглашению интерактивной оболочки )и nano
также унаследует его (, а стандартный вывод — это канал, используемый php
чтобы получить вывод nano
и передать его, nano
, кажется, доволен этим, не все редакторы, вы можете использовать system()
вместо этого здесь ).
В:
something | php -r 'passthru("nano");'
Вы вызываете php
с его stdin теперь канал с something
stdout на другом конце. И nano
унаследует его.
Если вы хотите, чтобы stdin php
был каналом, а nano
stdin каким бы ни был stdin оболочки, вам нужно каким-то образом передать этот ресурс на php
и иметьphp
(или оболочку запускаемыйpassthru
)сделать его стандартным для nano
.Это можно сделать, например, с помощью:
{ something 3<&- | php -r 'passthru("nano <&3 3<&-");'; } 3<&0
Где мы делаем ресурс на fd 0 (stdin )также доступным на fd 3 в группе команд ({...;}
), закрываем его для something
, которому он не нужен (3<&-
), и сообщаем оболочка, запускаемая php passthru
для восстановления stdin из этого fd 3.
Пример:
$ 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 — это tty-устройство для терминального взаимодействия.
$ 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
Теперь stdin ls
является каналом (, который echo
подает ).
$ { 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
ls
stdin снова стал устройством tty, в то время как его родитель (php )по-прежнему имеет канал на stdin (см. также tty на fd 3 и еще один канал на fd 4, вероятно, тот он читает вывод ls
с помощью ).
Итак, здесь вам нужно изменить ваш php-скрипт на:
<?php
foreach(file("php://stdin") as $name) {
echo "Hello $name";
passthru("nano <&3 3<&-");
}
?>
И назовите это как:
{ printf '%s\n' World Everybody | php script.php; } 3<&0
Для передачи обоих ресурсов (канал из printf
и исходный стандартный ввод )в php
.
Если вы ожидаете, что скрипт php
всегда будет вызываться из терминала и что nano
должен затем всегда взаимодействовать с терминалом (, но опять же, обратите внимание, что php
делает свой стандартный выводне терминал ), вместо этого вы можете изменить его на:
<?php
foreach(file("php://stdin") as $name) {
echo "Hello $name";
passthru("nano < /dev/tty");
}
?>
Где мы жестко -кодируем nano
stdin как управляющий терминал.
Я вижу это все время, но это еще не было проблемой. У меня это появилось там, где я работал. Это беспокоило меня в течение некоторого времени, пока мы не выяснили, что это было вызвано тем, как сетевая команда разделила что-то на подсети в нашей сети.
Также были замечены локальные приложения, вызывающие 0.0.0.0, и это вызывало локальную марсианскую генерацию. Может быть, посмотрите /etc/hosts/ для неправильной конфигурации. Я бы попытался выяснить, что вызывает это, прежде чем отключить его!
Запись марсианских попаданий в /var/log/messages можно отключить, добавив net.ipv4.conf.all.log _марсиане = 0 в /etc/sysctl.conf
без перезагрузки:
sysctl -w net.ipv4.conf.all.log_martians = 0
echo "net.ipv4.conf.all.log_martians = 0" >> /etc/sysctl.conf
Это может быть неверная конфигурация или попытка атаки со стороны кого-то, кто не может (надежно )подделать исходные адреса. Оба заслуживают расследования.