简体   繁体   English

如何从一个初始启动脚本生成多个bash后台脚本以登录终端的正确行?

[英]How can I get multiple bash background scripts, spawned from one initial startup script to log on the correct line of the terminal?

I have a bash script something like this: 我有一个像这样的bash脚本:

# one.sh, two.sh and three.sh do not depend on anything,
# and can run simultaneously in any order,
# and the execution time for each is random

# four.sh can only run once three.sh has finished

one.sh &
ONE=$!

two.sh &
TWO=$!

three.sh &
THREE=$!

wait $THREE
four.sh

where one.sh, two.sh and three.sh look something like this: 其中one.sh,two.sh和three.sh看起来像这样:

echo -n "doing stuff..."
#some command or set of commands
if [ $? ]
then
    echo $RESULT_PASS
else
    echo $RESULT_FAIL
fi

the output i'm getting is something like this: 我得到的输出是这样的:

doing stuff1...done
doing stuff2...
doing stuff3...
doing stuff4...done
7263
doing stuff5...done
doing stuff6...9823
doing stuff7...done 
9283

because some tasks in one script are not complete before tasks in another script have started. 因为在另一个脚本中的任务开始之前,一个脚本中的某些任务未完成。

the output i'm looking for is something like this: 我正在寻找的输出是这样的:

doing stuff1...done
doing stuff2...done
doing stuff3...8373
doing stuff4...done
doing stuff5...1234
doing stuff6...fail
doing stuff7...done

I would be grateful for some guidance. 我会感激一些指导。

Thanks! 谢谢!

I would use GNU Parallel to run scripts in parallel. 我会使用GNU Parallel并行运行脚本。 It is very simple, intuitive and flexible. 它非常简单,直观和灵活。 So, to run three scripts in parallel and keep the output in order and wait till all three have finished: 因此,要并行运行三个脚本并保持输出顺序并等到所有三个脚本完成:

parallel -k ::: ./one.sh ./two.sh ./three.sh

Sample Output 样本输出

doing stuff1...pass
doing stuff2...pass
doing stuff3...pass

Search for examples on Stack Overflow by typing [gnu-parallel] in the search box - include the square brackets. 通过在搜索框中键入[gnu-parallel]来搜索Stack Overflow上的示例 - 包括方括号。 You can run as many as you want in parallel, tag the output lines, round-robin large files across multiple processes, remote login to other machines to spread processes across a network, halt all other scripts if one fails, or if 10% fail, or if any pass... 您可以并行运行任意数量的运行,标记输出行,跨多个进程循环大文件,远程登录到其他计算机以跨网络传播进程,如果一个失败,则停止所有其他脚本,或者10%失败,或任何通行证......


Or you can ask GNU Parallel to tag each line with the name of the script: 或者您可以要求GNU Parallel使用脚本的名称标记每一行:

parallel -k --tag ::: ./one.sh ./two.sh ./three.sh
./one.sh    doing stuff1...pass
./two.sh    doing stuff2...pass
./three.sh  doing stuff3...pass

Than you need to use wait in the correct order. 比你需要使用正确的顺序wait Keep in mind that you can't know for sure when a process is finished, so you can't echo text in your child process and expect it to be printed in order. 请记住,您无法确定进程何时完成,因此您无法在子进程中回显文本并希望按顺序打印。 You should handle the output in the parent script. 您应该在父脚本中处理输出。

#! /bin/bash
PIDS=(0 0 0)
CMDS=("sleep 1" "sleep 2" "sleep 1 && exit 1")
X=0

IFS=$'\n'
for i in "${CMDS[@]}"; do 
    eval "$i &"
    PIDS[$X]=$!
    ((X++))
done

for ((i=0; i < $X; i++)); do
    wait ${PIDS[$i]}
    echo "Exit status is $?"
done
exit 0

I've created a similar script before which might be helpful. 我创建了一个类似的脚本,之前可能会有所帮助。

If you want commands to run concurrently and have their output not interleaved, you'll need to work at it. 如果您希望命令同时运行并且输出不是交错的,那么您需要使用它。 You can try moving the cursor around the screen....but it' really better if you do not. 您可以尝试在屏幕上移动光标....但如果不这样做,它会更好。 Doing this will make it so that your tool can only be used interactively which will greatly limit its scope. 这样做会使您的工具只能以交互方式使用,这将极大地限制其范围。 However, if you choose to ignore that advice, you can try something like: 但是,如果您选择忽略该建议,您可以尝试以下方法:

#!/bin/sh

output() {
        # Write a message on line $1 of the tty
        local mv=$(tput cup $1 0)
        local clear=$(tput el)
        printf "%s%s%s" "$mv" "$2" "$clear"

}

do_stuff() {
        i=0
        log() {
                output $1 "$( printf "doing stuff$1 %s" $2 )"
        }
        while sleep ${3-1} && test $i -lt $2; do
                log $1 "...$((i++))"
        done
        log $1 done
}

tput clear
do_stuff 1 5 .5 &
do_stuff 2 12 .2 &
do_stuff 3 16 .1
do_stuff 4 15 .2 &
wait
echo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM