Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash: Split stdout from multiple concurrent commands into columns

Tags:

linux

bash

shell

I am running multiple commands in a bash script using single ampersands like so:

commandA & commandB & commandC

They each have their own stdout output but they are all mixed together and flood the console in an incoherent mess.

I'm wondering if there is an easy way to pipe their outputs into their own columns... using the column command or something similar. ie. something like:

commandA | column -1 & commandB | column -2 & commandC | column -3

New to this kind of thing, but from initial digging it seems something like pr might be the ticket? or the column command...?

like image 980
Arjun Mehta Avatar asked Jun 11 '14 23:06

Arjun Mehta


2 Answers

Regrettably answering my own question.

None of the supplied solutions were exactly what I was looking for. So I developed my own command line utility: multiview. Maybe others will benefit?

It works by piping processes' stdout/stderr to a command interface and then by launching a "viewer" to see their outputs in columns:

fooProcess | multiview -s & \
barProcess | multiview -s & \
bazProcess | multiview -s & \
multiview

This will display a neatly organized column view of their outputs. You can name each process as well by adding a string after the -s flag:

fooProcess | multiview -s "foo" & \
barProcess | multiview -s "bar" & \
bazProcess | multiview -s "baz" & \
multiview

There are a few other options, but thats the gist of it.

Hope this helps!

like image 97
Arjun Mehta Avatar answered Oct 18 '22 08:10

Arjun Mehta


pr is a solution, but not a perfect one. Consider this, which uses process substitution (<(command) syntax):

pr -m -t <(while true; do echo 12; sleep 1; done) \
         <(while true; do echo 34; sleep 2; done)

This produces a marching column of the following:

12                                  34
12                                  34
12                                  34
12                                  34

Though this trivially provides the output you want, the columns do not advance individually—they advance together when all files have provided the same output. This is tricky, because in theory the first column should produce twice as much output as the second one.

You may want to investigate invoking tmux or screen in a tiled mode to allow the columns to scroll separately. A terminal multiplexer will provide the necessary machinery to buffer output and scroll it independently, which is important when showing output side-by-side without allowing excessive output from commandB to scroll commandA and commandC off-screen. Remember that scrolling each column separately will require a lot of screen redrawing, and the only way to avoid screen redraws is to have all three columns produce output simultaneously.

As a last-ditch solution, consider piping each output to a command that indents each column by a different number of characters:

this is something that commandA outputs and is
    and here is something that commandB outputs
interleaved with the other output, but visually
you might have an easier time distinguishing one
        here is something that commandC outputs
    which is also interleaved with the others
from the other
like image 21
Jeff Bowman Avatar answered Oct 18 '22 07:10

Jeff Bowman