watching output of "ps aux | grep blah" in tmux will not work?

I am trying to run this - watch "ps aux | grep myShittyProcess" in a tmux session. This process myShittyProcess was also started in a tmux session. The ps aux works without watch command. But as soon as I put it into watch, it fails to execute. How to get this to work?

-- edit -

Found that resizing tmux into full screen makes it work. Something to do with ps output wrapping and grep not able to find within wrapped context.


Solution 1:

As mentioned in the question edit and xzfc's answer, the issue seems to be related to tmux's line wrapping. For something closer to a drop-in replacement of ps aux | grep [q]uote, if you don't need user information, try:

$ pgrep -af [q]uote
392 bash -c sleep 5 && echo quote
399 bash -c sleep 5 && echo second quote

$ watch pgrep -af [q]uote

The -a flag makes the output include the command line arguments, while -f lets you search the command line arguments as well as just the process name.

Solution 2:

Run

watch "COLUMNS= ps aux | grep TheProcessYouWatch"

Explanation: watch sets certain additional env variables, namely COLUMNS and LINES. This can be easily verified by comparing env | grep COLUMNS and watch 'env | grep COLUMNS'.

When COLUMNS is set, ps truncates its output to that many characters in a line, even if the output is piped to grep (or anything else). (ps, why do you do this to me?). Forcing COLUMNS to be empty within watch's command is sufficient to make ps work as OP (and I) expected.

Btw, to avoid watch and grep processes being part of your watched output, consider adding [] like this:

watch "COLUMNS= ps aux | grep [T]heProcessYouWatch"

(Of course, I'd recommend to get familiar with pgrep too. Other answers will be helpful with this.)

Solution 3:

ps is utility that produces human-readable output, and rely on grepping human-readable text is bad idea. You should use pgrep myShittyProcess instead of ps aux | grep myShittyProcess. pgrep produces bare list of pids, and if you want less boring output, you can pass pgrep's output to ps:

ps -opid,user,args -p `pgrep myShittyProcess`

To use that one-liner with watch you should enclose it in ' ' (not " ") to prevent early shell command substitution:

watch 'ps -opid,user,args -p `pgrep myShittyProcess`'