バックグラウンドジョブでコマンドを実行し、bashスクリプトで結果を待つ方法

バックグラウンドジョブでコマンドを実行し、bashスクリプトで結果を待つ方法

特定のコマンドのプロセスを生成し、実行中にその出力をキャプチャする方法は?

たとえば、ブロックに対してタスクを実行しようとしていますが、ブロックがタスクを実行してステータスメッセージを生成しているdd間は、dd進行状況の出力を使用して他のタスクを実行します。次のスクリプトがありますが、印刷は中断されません。

#!/bin/bash

data=$(dd if=/dev/urandom of=/dev/null bs=4096 count=32768 status=progress)&

while [ -z "$data" ]; do
 echo "waiting for data..." "${data}"
 # Do something else while $data is not returned
 sleep 0.1
done

私は少し進歩しましたが、それでも私が望むものではありません。

    #! /bin/bash
    
    varFileDone=$(mktemp)
    varFileOutput=$(mktemp)
    
    dd if=/dev/urandom of=/dev/null bs=4096 \
count=32768 status=progress 2<&1 >> $varFileOutput && echo 1 > $varFileDone &
    pid=$(pidof dd)
    
    while [[ ! -s $varFileDone ]];
    do
    
    data=$(cat $varFileOutput)
    echo "----->" "$data"
    if [[ -s $data ]];
      then
        echo "we have data"
        echo $data | cut -d"," -f3
      else
        echo "no data yet!"
      fi
      sleep 0.2
    done

答え1

あなたの質問は少しあいまいです。非同期環境での変数設定の使用は、元の環境で変数値を使用できないため、ここではあまり効果的ではありません。

&記号を使用した非同期呼び出し&はで置き換えることができますcoproc。この形式を使用するいくつかのツールがあるので、bashのマニュアルページを見てください。

使用例:

#!/bin/bash

coproc COPROC ($(dd if=/dev/urandom of=/dev/null bs=4096 count=32768))

while [[ $COPROC ]]; do  
sleep 0.1
echo waiting!  
done

wait # unnecessary, but proves the asynchronous processes are actually complete
echo "Task done!"

答え2

あなたは試すことができます:

dd if=/dev/urandom of=/dev/null bs=4096 count=32768 & 2>&1 > /tmp/tmp
pid=$(ps|grep dd|awk '{print $1}')
while [[ ! "" = "$pid" ]]
do     
    # Do something else while dd is still writing

    grep "," /tmp/tmp | grep -v "+"|awk '{$2" "$3}'
done

答え3

ddコマンド出力を表示したくない場合は、次のようにリダイレクトを追加できます。

data=$(dd if=/dev/urandom of=/dev/null bs=4096 count=32768 2>&1 /dev/null)

2>&1出力とエラーをリダイレクトするために使用されます。

必要な出力を修正してください(/dev/null別のファイルと交換)。tailieコマンドを使用して、プロセスによって生成された出力を確認できますtail -f /your/output/file

関連情報