It is true. Even on the latest FreeBSD 11.0 (I checked the source tree).
ps | grep procName can fail.
$(ps -p pid) can fail.
ps itself on a non-interactive shell can fail.
They can fail if procName comes somewhere after 79 characters (e.g. /abc/def/ghi/…/procName).
Or if you’re using ps -o comm= and trying to match against a command
line, it can fail if the command line became too long.
79 ought to be enough
I looked up the source code for FreeBSD (8.4) ps, and here it is:
/* ... */
else if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&ws) == -1 &&
ioctl(STDERR_FILENO, TIOCGWINSZ, (char *)&ws) == -1 &&
ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&ws) == -1) ||
ws.ws_col == 0)
termwidth = 79;
What that’s saying is: if you’re not on a terminal, or if your system is unable to tell us how wide your terminal is, then we’ll assume your terminal is 79 characters wide!
I wrote a program to test when the ioctl() above returns non-zero.
It does if:
- You’re piping
psto another program, saygrep - You’re running a non-interactive shell (e.g. over ssh: Ansible!)
Shouldn’t we assume unlimited width, if we’re not really writing to a terminal? Go figure.
The fix
Anyway, the fix is: Use the -w option. TWICE. So it is actually:
-ww. Unless you want your terminal to only go up from 79 to 131
characters. I’m not kidding!
case 'w':
if (wflag)
termwidth = UNLIMITED;
else if (termwidth < 131)
termwidth = 131;
wflag++;
break;
So, please use: ps -ww | grep procName. Thank you.
What about Linux and Mac?
Both of these systems behave OK. Linux gets ps from procps, which
has this piece of code:
142 if(!isatty(STDOUT_FILENO)) screen_cols = OUTBUF_SIZE;
The ps on Mac works as expected, although the man page says it’s
derived from BSD. Did Steve Jobs run into it and then get it fixed?
;-)
Update Feb 16 2017
I’ve filed a defect and also uploaded a patch on FreeBSD’s bug database: BUG217159
Update Mar 5 2017
This has been accepted into mainline FreeBSD code. More info.