Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Process] Passing standard IO streams to executed process AKA calling an interactive application with cross-platform support #39482

Copy link
Copy link
Closed
@arnegroskurth

Description

@arnegroskurth
Issue body actions

Symfony version(s) affected: 5.2.0

Description

I would like to call an interactive application using the symfony process component without relying on any non-cross-platform functionality such as the allocation of a tty.

The support for this is indicated in the docs as "Using PHP Streams as the Standard Input of a Process": https://symfony.com/doc/current/components/process.html#using-php-streams-as-the-standard-input-of-a-process
(Originally implemented here: #18386)

Now when trying this using the code below, multiple problems arise:

  • Using bash on linux:
    • The shell prompt is not shown
    • Output of programs (e.g. nano) with complex CLI-renderings (e.g. using ncurses) is partially broken but can be interacted with using the standard input just fine.
    • The process instance does not seem to realize when closing the executed bash by writing exit. The process does not stop but any subsequent input produces an infinite loop with:
    PHP Notice:  fwrite(): write of 5 bytes failed with errno=32 Broken pipe in .../vendor/symfony/process/Pipes/AbstractPipes. PHP on line 128
    PHP Stack trace:
    PHP   1. {main}() .../test.php:0
    PHP   2. Symfony\Component\Process\Process->mustRun() .../test.php:15
    PHP   3. Symfony\Component\Process\Process->run() .../vendor/symfony/process/Process.php:256
    PHP   4. Symfony\Component\Process\Process->wait() .../vendor/symfony/process/Process.php:239
    PHP   5. Symfony\Component\Process\Process->readPipes() .../vendor/symfony/process/Process.php:417
    PHP   6. Symfony\Component\Process\Pipes\UnixPipes->readAndWrite() .../vendor/symfony/process/Process.php:1424
    PHP   7. Symfony\Component\Process\Pipes\UnixPipes->write() .../vendor/symfony/process/Pipes/UnixPipes.php:95
    PHP   8. fwrite() .../vendor/symfony/process/Pipes/AbstractPipes.php:128
    PHP Notice:  fwrite(): write of 5 bytes failed with errno=32 Broken pipe in .../vendor/symfony/process/Pipes/AbstractPipes. PHP on line 128
    ...
    
  • Using git-bash on Windows 10:
    • Interactive input seems to get ignored altogether yielding no (visible) output on any input

How to reproduce

<?php

require_once __DIR__ . '/vendor/autoload.php';

$process = new \Symfony\Component\Process\Process(['bash']);
$process->setInput(STDIN);
$process->mustRun(function(string $type, string $buffer) {

    switch ($type)
    {
        case 'err': fputs(STDERR, $buffer); break;
        case 'out': fputs(STDOUT, $buffer); break;
        default: throw new LogicException("Unknown output type: {$type}");
    }
});

Possible Solution

I don't have a possible solution for the symfony component but the desired behaviour can be achieved with plain php like this:

<?php
proc_close(proc_open('bash', [STDIN, STDOUT, STDOUT], $_));

Additional context

Related issues have been discussed here:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.