web-dev-qa-db-ja.com

GNUプログラムが終了する前の並列出力stdoutはできますか?

echo bash -c \''echo "hello, world!";sleep 3;'\' | parallel

このコマンドは、完了するまで何も出力しません。 Parallelのmanページは次のように主張しています。

GNU Parallelは、コマンドからの出力が、コマンドを順次実行した場合に得られる出力と同じであることを確認します。

悪魔は言い回しの中にあると思います。通常のように実行した場合と同じ出力が得られますが、通常の場合と同じ出力は得られません。これを行うオプションを探しました。たとえば、--results /dev/stdout、しかしそれはうまくいきません。

私のユースケースは、実行しているコマンドからのリアルタイムの進行状況出力を確認しています。完了したタスクの数ではなく、並列で表示できるのではなく、各コマンドの進行状況の出力を個別に確認したいのです。

私はbashループ(for i in $x; do cmd & done;)でも、単一のCtrl + Cですべてのタスクを停止できるようにしたいので、並行して実行できます。

これを並行して行うことは可能ですか?そうでない場合、別のツールはありますか?

7
Luc

--ungroupを探しているようです。マンページは言う:

--group  Group output. Output from each jobs is grouped 
         together and is only printed when the command is finished. 

         --group is the default. Can be reversed with -u.

もちろん-u--ungroupの同義語です。

10
ilkkachu

いくつかの並列ジョブの進行状況を監視するには、--tmuxpane --fgを試してください:

parallel --tmuxpane --fg seq {} 10000000 ::: {1..100}

-uまたは(可能性が高い)--lbを検索することもできます。 man parallelから:

   --line-buffer
   --lb
       Buffer output on line basis. --group will keep the output together
       for a whole job. --ungroup allows output to mixup with half a line
       coming from one job and half a line coming from another job.
       --line-buffer fits between these two: GNU parallel will print a full
       line, but will allow for mixing lines of different jobs.

       --line-buffer takes more CPU power than both --group and --ungroup,
       but can be much faster than --group if the CPU is not the limiting
       factor.

       Normally --line-buffer does not buffer on disk, and can thus process
       an infinite amount of data, but it will buffer on disk when combined
       with: --keep-order, --results, --compress, and --files. This will
       make it as slow as --group and will limit output to the available
       disk space.

       With --keep-order --line-buffer will output lines from the first job
       while it is running, then lines from the second job while that is
       running. It will buffer full lines, but jobs will not mix. Compare:

         parallel -j0 'echo {};sleep {};echo {}' ::: 1 3 2 4
         parallel -j0 --lb 'echo {};sleep {};echo {}' ::: 1 3 2 4
         parallel -j0 -k --lb 'echo {};sleep {};echo {}' ::: 1 3 2 4

       See also: --group --ungroup

[...]

   --ungroup
   -u  Ungroup output.  Output is printed as soon as possible and by passes
       GNU parallel internal processing. This may cause output from
       different commands to be mixed thus should only be used if you do not
       care about the output. Compare these:

         seq 4 | parallel -j0 \
           'sleep {};echo -n start{};sleep {};echo {}end'
         seq 4 | parallel -u -j0 \
           'sleep {};echo -n start{};sleep {};echo {}end'

       It also disables --tag. GNU parallel outputs faster with -u. Compare
       the speeds of these:

         parallel seq ::: 300000000 >/dev/null
         parallel -u seq ::: 300000000 >/dev/null
         parallel --line-buffer seq ::: 300000000 >/dev/null

       Can be reversed with --group.

       See also: --line-buffer --group

-uが輝く1つの例は、stdoutとstderrが同じ行に混在している場合です。

echo -n 'This is stdout (';echo -n stderr >&2 ; echo ')'

これは、--lbおよび--groupで誤ってフォーマットされます。

しかし-uでも、プロセス間の半行混合のため、正しくフォーマットされることを保証しません: http://mywiki.wooledge.org/BashPitfalls#Non-atomic_writes_with_xargs_-P

6
Ole Tange