proc_open and pty’s

By Harry Fuecks

Something from my inbox (best read bottom up), following on from CLI Part 2 any takers?


Now i’m working now with PHP
Version 5.0.1


Version 5.0.0 Release Candidate 2* *25-Apr-2004


* Added pty support to proc_open(). (Wez)


PHP 5RC2 introduces pty support for systems with Unix98 ptys. This
allows your script to interact with applications that expect to be
talking to a terminal. A pty works like a pipe, but is bi-directional,
so there is no need to specify a read/write mode. The example below
shows how to use a pty; note that you don’t have to have all descriptors
talking to a pty. Also note that only one pty is created, even though
pty is specified 3 times. In a future version of PHP, it might be
possible to do more than just read and write to the pty.
The file descriptor numbers in descriptorspec are not limited to 0, 1
and 2 – you may specify any valid file descriptor number and it will be
passed to the child process. This allows your script to interoperate
with other scripts that run as “co-processes”. *In particular, this is
useful for passing passphrases to programs like PGP, GPG and openssl in
a more secure manner*. It is also useful for reading status information
provided by those programs on auxiliary file descriptors.

Right? Here is my script…

1 => array("pty"),
2 => array("pty")
$process = proc_open("/usr/bin/passwd", $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], "mypasswd");

while (!feof($pipes[1])) {
echo fgets($pipes[1], 1024);
// It is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
$return_value = proc_close($process);

echo "command returned $return_valuen";

BUT… when i ran the program:

username:~/Sites/Grid david$ php pty.php
this is a test
Warning: proc_open(): pty is not a valid descriptor spec/mode in
/Users/david/Sites/Grid/pty.php on line 10

$process = proc_open("/usr/bin/passwd", $descriptorspec, $pipes);

Could you help me,please?

> Hi David,


> No sure it is a newbie question ;) This isn’t one I’ve tried but PHP

> 5+ should

> (in theory) allow this with the proc_open function, covered in the

> second PHP

> CLI article. The manual has some notes

> You need a descriptor spec something like;


> $descriptorspec = array(

> 0 => array(“pty”),

> 1 => array(“pty”),

> 2 => array(“pty”)

> );


> Would be interested to hear how you get on.


>> ———————————————————–

>> From: “David”

>> Message: This is a newbie question, maybe i need a big RTFM. It’s

>> very interesting and useful your two articles “PHP on the Command

>> Line”.


>> I have a big doubt… We are working with PHP 4.3.3 I have to

>> write a PHP script to change a unix user password.


>> Something like that



>> Is possible to do it with PHP? Thank you

>> in advances.

  • sweatje

    This worked for me on linux:

    $descriptorspec = array(
    0 => array("pipe", "r"), // stdin is a pipe that the child will read from
    1 => array("pipe", "w"), // stdout is a pipe that the child will write to
    2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
    $process = proc_open('bash', $descriptorspec, $pipes);
    if (is_resource($process)) {
    fwrite($pipes[0], "passwdn");
    fwrite($pipes[0], "$oldpassn");
    fwrite($pipes[0], "$newpassn");
    fwrite($pipes[0], "$newpassn");

    while (!feof($pipes[1])) {
    echo fgets($pipes[1], 1024);
    $return_value = proc_close($process);

    echo "ncommand returned $return_valuen";

    • Anonymous

      sweatje’s solution worked awesome. many thanks.

  • HarryF

    Nice one – should have realised passwd would use STDIN / OUT.

  • sweatje

    [quote=”HarryF”]should have realised passwd would use STDIN / OUT.[/quote]
    Whole point of your post-php can now act like a console user :)

    The only thing that was close to a “trick” in the code was choosing a shell interpreter, bash in this case, as the process to open initially.

    Also, since you are running this at the command line, inside of php you are running with all your own permissions, so this really is no better than just running passwd yourself. In a way, just a bit of a pointless excersise as it is simply adding another layer, but kind of cool to know the possibility is out there :)



Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Front-end, once a week, for free.