PHP output piped to 'less' is requiring <enter> after every command

5

0

Piping PHP output to the linux 'less' command causes 'less' to really act up. (CentOS 6.2, didn't happen with CentOS 5.)

When I pipe output from php into 'less', it requires the enter key be pressed after every command, even after the 'j' command (the command to scroll down one line). In addition, the command key is showing up on-screen, and 'less' isn't cleaning up the screen.

So, after running:

$ php -r 'for ($i=0; $i<300; $i++) { print "$i\n";}' | less

and then typing j (which usually scrolls down one line), I see a 'j' character showing up at the bottom of the screen after the ':' character. Pressing enter causes less to finally "take" the j command, and it does indeed scroll, but now I see the ":j" between two adjacent lines of the output:

10
:j
11

When using less with the equivalent output from python, everything is fine and less acts normally:

$ python -c 'for i in xrange(1, 300): print i' | less

What's going on and how do I fix it?

More info:

$ less --version
less 436
Copyright (C) 1984-2009 Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less

$ php --version
PHP 5.3.27 (cli) (built: Aug 26 2013 11:46:37)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2013 Zend Technologies

I'm using Terminal.app on Mac OS X to ssh to the box, then running the php command.

Eddified

Posted 2013-11-22T19:49:12.063

Reputation: 1 440

1Its probably a terminal setting (what does echo $TERM say). I tried the same script in my CentOS 6.2 box and it worked as expected. I wonder if it might be to do with the way your terminal is intepreting CR and LF. What happens if you use "\r\n" rather then just "\n" ? – davidgo – 2013-11-22T21:22:57.080

The $TERM is 'screen'. :) If I try it without screen, it says 'xterm-256color' and still doesn't work right. – Eddified – 2013-11-22T22:07:22.780

Nor Ubuntu 13.04 nor Debian Testing do this. I would blame their less implementation. – Braiam – 2013-11-26T00:46:20.710

What version of CentOS 5 did this work? I'm on 5.9 and it exhibits the same problems you're highlighting for 6.2. – slm – 2013-11-26T02:58:01.000

It is working correctly on my CentOS 5.5 install. – Eddified – 2013-11-26T17:13:52.070

Please could you add following details: less --version and php --version?

PS Could be that PHP recognizes only php -v for querying the version number. – t0r0X – 2013-12-02T18:12:15.743

More questions: are you trying this in a terminal window in a graphical environment, directly in a non-graphic console, or via a terminal/ssh/telnet program? – t0r0X – 2013-12-02T18:20:09.050

Answers

7

Edit:

Found the solution: You need to do a < /dev/null after the PHP command:

php -r 'for ($i=0; $i<300; $i++) { print "$i\n";}' < /dev/null | less

Apparently PHP behaves differently because it still expects input from stdin.
With the < /dev/null you force PHP into thinking there is no further input.

Edit 2:

If you don't want to (keep) typing the < /dev/null you can create an alias for php2 or something:

alias php2="php < /dev/null`

You can make this permanent if you add it in your ~/.bashrc.

Now you can do:

php2 -r 'for ($i=0; $i<300; $i++) { print "$i\n";}' | less

You could alias php to itself but then you'll never have the ability to pipe something into php.
You could of course shorten it to p (for less typing).


Original answer:

The bug is also present in CentOS 6.5.

A newly installed CentOS 6.5 has it too (in a VM). A ... | cat | less does not work.
A ... > a && cat a | less does work. Go figure.

Cursor keys also don't work in php --help | less. They do work in python --help | less. So it must be something in the PHP executable. I think this is a longstanding bug in PHP.

I found a reference to this bug here.

Until it is fixed you need to do a redirect:

php -r 'for ($i=0; $i<300; $i++) { print "$i\n";}' > /tmp/php.txt && cat /tmp/php.txt | less

Rik

Posted 2013-11-22T19:49:12.063

Reputation: 11 800

I had already figured the ... > tmpfile && cat tmpfile | less workaround on my own... it is a very annoying workaround, but does work. The < /dev/null workaround is better but is still only a workaround, but I gave you the bounty for effort. :) – Eddified – 2013-12-02T22:52:06.190

I personally think that while PHP may have a bug here, less also has a bug. Usually (i.e. with CentOS 5) when I have a long-running program, less can still be used normally while php continues to produce output. – Eddified – 2013-12-02T23:05:24.237

I added an Edit #2. You can use alias (e.g. php2) to "ease the pain" :) Did you have the same PHP version (5.3.3 ?) in CentOS 5 as the one in CentOS 6.2? – Rik – 2013-12-02T23:13:32.483

No, I had a different php version before (5.1). – Eddified – 2013-12-03T00:16:16.150

I guess we need someone with a RPM install of PHP 5.3.28+ on CentOS 5 to test this. Or a PHP 5.1.x install on CentOS 6.2+. – Rik – 2013-12-03T00:42:22.040

It definitively a PHP issue. I made a snapshot of my CentOS 6.5, removed PHP 5.3.3, installed a RPM of PHP 5.2.17 (and its dependencies) and the problem was solved. After re-installing the standard package from CentOS 6.5 again (PHP 5.3.3) the problem was there again. So this problem surfaces between version 5.2.17 and 5.3.27 of PHP. – Rik – 2013-12-03T08:07:54.743

2

This is a weird behaviour, hard to reproduce... Have you tried setting TERM to plain xterm

export TERM=xterm

or vt100?

export TERM=vt100

Try to manually set the window size (number of lines to scroll, usually == number of lines of your window/console):

...| less --window=80

or try

... |less --raw-control-chars

or

... |less --RAW-CONTROL-CHARS

PS Oh, by the way, CentOS 6.2 was release in June 2012, have you thought about an upgrade to a newer version? The current CentOS version is 6.5 ...

t0r0X

Posted 2013-11-22T19:49:12.063

Reputation: 144

None of these suggestions worked. I do not have control over the CentOS version. – Eddified – 2013-12-02T17:53:58.113

Does it behave better when you pipe it through another program? E.g. ... | cat | less – t0r0X – 2013-12-02T18:06:17.137

... | cat | less does not help. – Eddified – 2013-12-02T22:47:17.423