Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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.

share|improve this question
1  
Its 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 Nov 22 '13 at 21:22
    
The $TERM is 'screen'. :) If I try it without screen, it says 'xterm-256color' and still doesn't work right. –  Eddified Nov 22 '13 at 22:07
    
Nor Ubuntu 13.04 nor Debian Testing do this. I would blame their less implementation. –  Braiam Nov 26 '13 at 0:46
    
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 Nov 26 '13 at 2:58
    
It is working correctly on my CentOS 5.5 install. –  Eddified Nov 26 '13 at 17:13

2 Answers 2

up vote 3 down vote accepted
+50

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
share|improve this answer
    
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 Dec 2 '13 at 22:52
    
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 Dec 2 '13 at 23:05
    
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 Dec 2 '13 at 23:13
    
No, I had a different php version before (5.1). –  Eddified Dec 3 '13 at 0:16
    
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 Dec 3 '13 at 0:42

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 ...

share|improve this answer
    
None of these suggestions worked. I do not have control over the CentOS version. –  Eddified Dec 2 '13 at 17:53
    
Does it behave better when you pipe it through another program? E.g. ... | cat | less –  Victor Dec 2 '13 at 18:06
    
... | cat | less does not help. –  Eddified Dec 2 '13 at 22:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.