4

I commonly run a lot of programs from the same shell before using the watch command to monitor the programs for completion. (I filter the ps command a bit, but this example is simpler.)

sleep 10 && for i in {1..100}; do echo $i; done &
watch -n 5 ps aux

The watch command clears the terminal so that the output of the command is clear and there is no clutter.

Output of watch command

When another program outputs such as the echo statements in the example, the result is a little weird. It prints strangely and the results seem to depend on the size of the output. Even though watch should have rerun the "ps aux" command, it does not overwrite the output of the "echo" commands.

After sleep timer has finished

Is there something like this that would prevent the output of other programs from covering watch output?

watch -n 5 ClearScreenSomehow && ps aux
Tony Ruth
  • 1,358
  • 8
  • 19
  • As written, this problem is not reproducible so it is difficult to help you. You'll need to add an example program that reproduces the undesirable behavior. – merlin2011 Dec 01 '15 at 01:25
  • Separate note, why does your binary have an `exe` extension on Linux? It doesn't hurt but it does seem a little strange and unnecessary. – merlin2011 Dec 01 '15 at 01:25
  • @merlin2011 I changed out the commands to make it so you can easily repeat the problem on your own terminal. I guess the exe thing is just a force of habit. – Tony Ruth Dec 01 '15 at 03:17

2 Answers2

2

I don't know if there is a simple way to do this. Until someone comes up with one, here's a complicated way to do this:

Consider the original case as control:

#delayed print to clutter up watch later
bash -c 'sleep 10; echo ASDF' &
#watch dummy command, observe cluttering
watch -n1 'ls -la |head -25'

My approach is to hijack all the processes that can clutter up your window, and throw their output into the abyss that is /dev/null.

A standard way of redirecting the output of already running processes is using gdb. In order to do it non-interactively, you have to use the -batch switch and a manual specification of the pid you want to redirect. The result is

bash -c 'sleep 10; echo ASDF' &
#sudo gdb -p "$!" -batch -ex 'p dup2(open("/dev/null",0),1)' -ex 'p dup2(open("/dev/null",0),2)' -ex 'detach'
gdb -p "$!" -batch -ex 'p dup2(open("/dev/null",0),1)' -ex 'p dup2(open("/dev/null",0),2)' -ex 'detach'
watch -n1 'ls -la |head -25'

where $! is the pid of the last spawned process, which is just what we need in our example. In your actual use case you'd have to loop over every pid running in the background of your given shell, and substitute each pid into $! above.

Also note that the gdb call should work without sudo for your own processes, but for some reason (stemming from some configuration) it only let me perform it with sudo. Your mileage may vary.

Community
  • 1
  • 1
1

The simple and obvious answer is to not run background commands which can produce output without redirection.

When you run something in the background, have it print to a file. Examine the file when you wish to see the output.

Some people also like to use screen or tmux to run separate jobs in separate virtual terminals. Or just open a separate xterm or similar for each process you want to run while doing something else.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Usually if I allow something to print to std out it is intentional. Maybe I watch the output to see if the program gets past the point where it crashed before and then it is okay to leave it and come back later. Other times, programs I was not expecting print error messages such as my IDE. I suppose I could append `> /dev/null` to all these calls, but it is somewhat tedious. – Tony Ruth Dec 02 '15 at 03:07