2016-08-16 21 views
3

サーバ間のデータ移行を実行するために私たちの主要なスクリプトの1つにパラレルを実装しました。現在、出力は、実行中のシーケンス(例えば、5/20: $username: rsyncing homedirまたは5/20: $username: restoring account)に応じて実行される機能からのステータスの定期的なエコーとともに、一度にすべての出力(-u)をきれいな色で表示します。これらはすべて、スクリプトを実行している端末に直接エコーされ、そこで蓄積されます。ただし、コマンドが実行されている時間の長さによっては、出力が正常に終了せず、長時間実行されているrsyncコマンドがシャッフル中に失われる可能性があります。 Butm私は、次のプロセスの出力を得るために、長時間実行されているプロセスが終了するのを待っていません。gnuの状態/進捗状況を平行にトラッキングする

要するに、私の問題は、どの引数が処理されていて、まだ実行中であるかを追跡しています。

私がしたいことは、(parallel args command {#} {} ::: $userlist) &でバックグラウンドに並列して送信し、次にそれぞれの実行中の機能の進捗状況を追跡することです。私の最初の考えはpsgrepを自由に使ってtputと一緒に数秒ごとに画面を書き直すことでした。例えば、私は通常、並列に3つのジョブを実行するので、私は表示する画面を持つようにしたい:

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: 

私は確かに一緒に何ら問題は上記のステータス出力を得ることはできませんが、私の現在のハングアップからの出力を分離しています個々の並列プロセスを3つの異なるパイプに変換しますか?変数?ファイル?上記の情報に解析することができます。

+0

あなたは--linebuffer --tagと--tmuxを認識していますか? –

+0

--tagは、出力をパイプして定期的に分析できるようにするためのアイデアを持っている人には便利です(現行の出力には、すべての引数が既にきちんとフォーマットされていることが示されています)。--line-bufferと--tmuxは役に立ちませんこの場合。私は特に出力から重複する行については心配していません(これはまれです)。実行中のプロセスではなく、tmuxからの情報のスクレイピングは余計なステップのようです(マシンにデフォルトでtmuxがインストールされていません)。 – Andrej

答えて

0

私は、これは、それは非常に整頓、おそらくイマイチ最適イマイチかかわらず、私は必要なものに近いと信じている:

#!/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からすべての情報をこするに依存しないだろうし、取得することを好むだろうそれぞれの並列プロセスの実際の行出力ですが、男は何をする必要がありますか?後で解析するためにログファイルに送られる通常の出力。これははるかに優れている場合

0

わからない:それは、ジョブごとにログファイルを作る

echo hello im starting now 
sleep 1 
# start parallel and send the job to the background 
temp=$(mktemp -d) 
parallel --rpl '{log} $_="Working [email protected]"' -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 ...」です。

+0

プロセスごとにログファイルをテーリングします。すぐ後で簡単に削除できるので、良い考えです。私は、> $ temp/synclog。{}。log 'をperl置換の代わりに並列でbackground()コマンドの一部として使用し、そのステータス行をlsofとpsの部分で表示してすべてを組み合わせることになります。 – Andrej