【问题标题】:tracking status/progress in gnu parallel在 gnu 中并行跟踪状态/进度
【发布时间】:2016-12-23 01:00:55
【问题描述】:

我已经在我们的一个主要脚本中实现了并行,以在服务器之间执行数据迁移。目前,输出以漂亮的颜色一次性呈现(-u),根据正在运行的序列(例如5/20: $username: rsyncing homedir5/20: $username: restoring account),正在执行的函数的状态周期性回显。这些都直接回显到运行脚本的终端,并在那里累积。但是,根据命令运行的时间长度,输出可能会完全乱序,并且长时间运行的rsync 命令可能会在随机播放中丢失。但是我不想等待长时间运行的进程完成才能获得后续进程的输出。

简而言之,我的问题是跟踪哪些参数正在处理并且仍在运行。

我想做的是使用(parallel args command {#} {} ::: $userlist) & 将并行发送到后台,然后跟踪每个正在运行的函数的进度。我最初的想法是使用psgrep 以及tput 每隔几秒重写一次屏幕。我通常并行运行三个作业,所以我希望有一个屏幕显示,例如:

1/20: user1: syncing homedir
current file: /home/user1/www/cache/file12589015.php

12/20: user12: syncing homedir
current file: /home/user12/mail/joe/mailfile

5/20: user5: collecting information
current file: 

我当然可以将上述状态输出放在一起没问题,但我目前的挂断是将来自各个并行进程的输出分成三个不同的......管道?变量?文件?这样就可以解析成上面的信息了。

【问题讨论】:

  • 你知道 --linebuffer --tag 和 --tmux 吗?
  • --tag 如果有人对管道输出有想法以便可以定期分析它可能很有用(尽管当前输出显示所有参数已经整齐地格式化),但是 --line-buffer和 --tmux 在这种情况下没有帮助。我并不特别担心与输出重叠的行(这种情况很少见),从 tmux 而不是正在运行的进程中抓取信息似乎是一个额外的步骤(加上我们的机器默认没有安装 tmux)

标签: bash gnu-parallel


【解决方案1】:

不确定这是否更好:

echo hello im starting now
sleep 1
# start parallel and send the job to the background
temp=$(mktemp -d)
parallel --rpl '{log} $_="Working on@arg"' -j3 background {} {#} ">$temp/{1log} 2>&1;rm $temp/{1log}" ::: foo bar baz foo bar baz one two three one two three :::+ 5 6 5 3 4 6 7 2 5 4 6 2 &
while kill -0 $!  2>/dev/null ; do
    cd "$temp"
    clear
    tail -vn1 *
    sleep 1
done
rm -rf "$temp"

它为每个作业创建一个日志文件。每秒跟踪所有日志文件,并在作业完成时删除日志文件。

日志文件被命名为'working on ...'。

【讨论】:

  • 跟踪每个进程的日志文件是个好主意,因为它可以在之后立即轻松删除。我想我最终会合并所有内容,使用 '>$temp/synclog.{}.log' 作为 background() 命令的一部分并行而不是 perl 替换,并使用 lsof 和 ps 部分打印该状态行。
【解决方案2】:

我相信这很接近我的需要,虽然它不是很整洁并且可能不是最佳的:

#!/bin/bash

background() { #dummy load. $1 is text, $2 is number, $3 is position
        echo $3: starting sleep...
        sleep $2
        echo $3: $1 slept for $2
}

progress() {
        echo starting progress loop for pid $1...
        while [ -d /proc/$1 ]; do
                clear
                tput cup 0 0
                runningprocs=`ps faux | grep background | egrep -v '(parallel|grep)'`
                numprocs=`echo "$runningprocs" | wc -l`
                for each in `seq 1 ${numprocs}`; do
                        line=`echo "$runningprocs" | head -n${each} | tail -n1`
                        seq=`echo $line | rev | awk '{print $3}' | rev`
                        # print select elements from the ps output
                        echo working on `echo $line | rev | awk '{print $3, $4, $5}' | rev`
                        # print the last line of the log for that sequence number
                        cat logfile.log | grep ^$seq\: | tail -n1
                        echo
                done
                sleep 1
        done
}

echo hello im starting now
sleep 1
export -f background
# start parallel and send the job to the background
parallel -u -j3 background {} {#} '>>' logfile.log ::: foo bar baz foo bar baz one two three one two three :::+ 5 6 5 3 4 6 7 2 5 4 6 2 &
pid=$!
progress $pid
echo finished!

我宁愿不依赖于从ps 抓取所有信息,而是更愿意获得每个并行进程的实际线路输出,但是一个人必须做一个人必须做的事情。常规输出发送到日志文件以供稍后解析。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-16
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 2023-01-03
    相关资源
    最近更新 更多