simple php/expect script works from command line but not from web

I have a really basic expect script which I call from php. I works fine when I run the php from the shell, but from the web it appears as if the output buffer gets chopped and never gets all of the contents.

php script: (runexpect.php)

<?php
shell_exec("/opt/bell/apache2/htdocs/www/expecttest/connect.exp > /tmp/connect.exp.out 2>&1 ");
?>

expect script (connect.exp)

#!/usr/local/bin/expect -f

set timeout 20
spawn telnet COVE-C2851-CE1
expect -re ".*Username:.*" 
send -- "jacksona\r"

expect -re ".*Password:.*"
send -- "xxxxx\r"
expect -re ".*COVE-C2851-CE1#.*"
send -- "exit\r"
expect eof

Output from running it from the web

I seems to connect to the device fine, but the buffer only contains up to "Escape character is '^]'." and never contains the "Username:" prompt so the script eventually times out. but running php ./runexpect.php from the command line works like a charm.

I have tried everything, but no luck .. please help me.

Telnet seems to connect but not get a prompt. Probably missing some ENV or the tty in the web case. Try comparing the kernel calls using truss/tusc/strace to see where it diverges. Make a truss/tusc/strace wrapper script for telnet.

It is weird because it is actually connect to the device. I can see from the debug output of expect that is get as far as connecting, but never sees the "Username:" prompt in the buffer

here is the debug ...

expect: does "Trying 167.70.219.133...\r\nConnected to COVE-C2851-CE1.\r\nEscape character is '^]'.\r\n" (spawn_id exp3) match regular expression ".*Username:.*"? no

When I snoop what is happening on the router side, it is actually sending back the Username prompt, but expect never sees it in the buffer. The other weird thing is that is works fine from both the command line and web when I ssh to the device.

Why not stick to ssh?

The terminal may be acting in canonical mode, reading line by line. In which case the login prompt, if not followed by a newline, won't be read.

Try forcing a certain terminal mode before you spawn ssh like stty raw -echo

If at all possible of course, ssh would be better. telnet is mostly obsolete these days and ssh doesn't need expect-hacking to automate.

I only turned on ssh for this box to test, but I am unfortunately many of our production devices are telnet. It appears that the expect buffer is not getting the "Username:" prompt eventhough the router is clearly sending it. I tried
"stty raw -echo but no luck.

Try not using -re where there is no linefeed. Use simple expect.

I was able to get it to work by doing this

exec("echo \". /opt/bell/apache2/htdocs/.profile;/opt/bell/apache2/htdocs/www/expecttest/connect.exp > /tmp/wrapper.out\" | at now ");

running in an "at" job it must get a real shell I am guessing, I still have no idea why it partially works the other way, but I have a cheesy fix and am happy.

Thanks for all your suggestions !