Bash:将stdout从多个并发命令拆分为列

时间:2014-06-11 23:41:45

标签: linux bash shell

我在bash脚本中使用单个&符号运行多个命令,如下所示:

commandA & commandB & commandC

他们每个人都有自己的stdout输出,但他们都是混合在一起的,并且在混乱的混乱中充斥着控制台。

我想知道是否有一种简单的方法可以将输出管道输入到他们自己的列中......使用column命令或类似命令。即。类似的东西:

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

这种事情的新手,但从最初的挖掘看起来似乎 pr 可能是票?或column命令......?

3 个答案:

答案 0 :(得分:5)

遗憾地回答了我自己的问题。

所提供的解决方案都不是我想要的。所以我开发了自己的命令行实用程序: multiview 。也许其他人会受益?

它适用于管道工艺' stdout / stderr到命令界面,然后启动一个"查看器"在列中查看其输出:

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

这将显示其输出的整齐有序的列视图。您也可以在-s标志后添加一个字符串来命名每个进程:

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

还有其他一些选择,但这就是它的要点。

希望这有帮助!

答案 1 :(得分:3)

pr是一个解决方案,但不是一个完美的解决方案。考虑一下,它使用process substitution<(command)语法):

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

这会产生以下行进栏:

12                                  34
12                                  34
12                                  34
12                                  34

虽然这可以简单地提供您想要的输出,但是列不会单独前进 - 当所有文件提供相同的输出时它们会一起前进。这很棘手,因为理论上第一列的输出应该是第二列的两倍。

您可能希望调查在平铺模式下调用tmuxscreen以允许列分别滚动。终端多路复用器将提供必要的机制来缓冲输出并独立滚动它,这在并排显示输出时很重要,而不允许commandB的过多输出滚动commandA和commandC off-screen。请记住,单独滚动每一列需要大量的屏幕重绘,避免屏幕重绘的唯一方法是让所有三列同时产生输出。

作为最后的解决方案,请考虑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

答案 2 :(得分:1)

脚本打印出三个垂直行和一个计时器,每行包含一个脚本的输出。 评论你不理解的任何内容,并根据需要添加我的答案的答案

希望这会有所帮助:)

#!/bin/bash
#Script by jidder

count=0
Elapsed=0
control_c()
{
    tput rmcup
    rm tail.tmp
    rm tail2.tmp
    rm tail3.tmp
    stty sane
}


Draw()
{
       tput clear
       echo "SCRIPT 1                                                                                                                     Elapsed time =$Elapsed seconds"
        echo "------------------------------------------------------------------------------------------------------------------------------------------------------"
        tail -n10 tail.tmp
        tput cup 25 0

        echo "Script 2                                                                                                                                                   "
        echo "------------------------------------------------------------------------------------------------------------------------------------------------------"
        tail -n10 tail2.tmp
        tput cup 50 0

        echo "Script 3                                                                                                                                                   "
        echo "------------------------------------------------------------------------------------------------------------------------------------------------------"
        tail -n10 tail3.tmp
}


Timer()
{
        if [[ $count -eq 10  ]]; then
                Draw
                ((Elapsed = Elapsed + 1))
                count=0
        fi


}
main()
{
    stty -icanon time 0 min 0
    tput smcup
    Draw
    count=0
    keypress=''
    MYSCRIPT1.sh > tail.tmp &
    MYSCRIPT2.sh > tail2.tmp &
    MYSCRIPT3.sh > tail3.tmp &

    while [ "$keypress" != "q" ]; do
            sleep 0.1
            read keypress
            (( count = count + 2 ))
            Timer
    done

    stty sane
    tput rmcup
    rm tail.tmp
    rm tail2.tmp
    rm tail3.tmp
    echo "Thanks for using this script."
    exit 0
}

main

trap control_c SIGINT