2017-12-08 19 views
2

以下、個々のコマンドのプロセスIDを収集し、それらをbashの配列に追加するスクリプトがあります。なんらかの理由で、以下のstdoutを見ることができますが、結果として得られる配列には最新のidという項目が1つだけ含まれています。このスクリプトの末尾にあるPROCESS_IDSアレイには、どのようにして4つのプロセスIDがすべて含まれていますか?ここでbashファイルの並列プロセスのプロセスIDの収集

PROCESS_IDS=() 

function append { 
    echo $1 
    PROCESS_IDS=("${PROCESS_IDS[@]}" $1) 
} 

sleep 1 && echo 'one' & append $! & 
sleep 5 && echo 'two' & append $! & 
sleep 1 && echo 'three' & append $! & 
sleep 5 && echo 'four' & append $! 
wait 

echo "${PROCESS_IDS[@]}" 

stdoutです:

83873 
83875 
83879 
83882 
three 
one 
four 
two 
83882 
+1

最初の3行の最後に末尾の '&'を削除してみてください。 – Pavel

+0

@pavelこれらの4行を並行して実行します。 – ThomasReggi

+0

私はちょうどあなたに聞いたことがありました。しかし、私はそれらを並行して実行したいと思います。私は 'append'の中の' $ 1'変数にまだアクセスしています。ちょうど 'echo'は正しく配列に正しく格納されていません。 – ThomasReggi

答えて

3

append操作自体をバックグラウンドに送信しないでください。 sleepechoはまだバックグラウンドにしているが、appendはありません:append&後の背景にしたいコンテンツが、を置くことは十分です。

process_ids=() 
append() { process_ids+=("$1"); }  # POSIX-standard function declaration syntax 

{ sleep 1 && echo 'one'; } & append "$!" 
{ sleep 5 && echo 'two'; } & append "$!" 
{ sleep 1 && echo 'three'; } & append "$!" 
{ sleep 5 && echo 'four'; } & append "$!" 

echo "Background processes:"    # Demonstrate that our array was populated 
printf ' - %s\n' "${process_ids[@]}" 

wait 
+0

それらを含めるにはおそらくスタイルは良いでしょうが、中かっこは必要ありません。'sleep 1 && echo one&'は '{sleep 1 && echo one;と同じです。 }& 'bashのマンページから:'これらのリスト演算子のうち、&&と||同じ優先順位を持ち、その後に続きます。 &、優先順位が同じです。 " –

+1

@WilliamPursell、* nod * - 私は"良いスタイル "に落ちています。ここでは、これは読者の行動の点であまりあいまいではありません。 –

1

私の推測では、あなたがバックグラウンドへの関数呼び出しを送信するたびが、それは自分自身でグローバル変数のコピーを持っているので、彼ら」ということですPIDをPROCESS_IDSの4つの独立したコピーに追加する。そのため、すべての関数呼び出しが空であることが分かり、その中に単一のPIDを格納するのです。

http://www.gnu.org/software/bash/manual/bashref.html#Lists

コマンドが制御演算子「&」により終了した場合、シェルはサブシェルで非同期コマンドを実行します。これは、バックグラウンドでコマンドを実行することとして知られています。

あなたがそれらをディスクに書き込むと最後に出力を読み聞かせて、4つのすべての関数呼び出しからの出力を収集する場合:

function append { 
    echo $1 | tee /tmp/file.$1 
} 

sleep 1 && echo 'one' & append $! & 
sleep 5 && echo 'two' & append $! & 
sleep 1 && echo 'three' & append $! & 
sleep 5 && echo 'four' & append $! 
wait 

cat /tmp/file.* 

編集:これは概念だけの証拠でありますとにかくファイルシステムでやってはいけません(ウィリアムが指摘したように、これは一意性と同期性を考慮しない限りエラーが起こりやすいでしょう)。私は、サブシェルから情報を取り出す別の方法を見つける必要があることを説明したかっただけです。

+0

良いアイデアだが、すべてのpidを1つのファイルに書き込む方がきれいだ。グロブ展開は、このスクリプトとは無関係のファイルを拾うかもしれません。 –

+1

「推測」は正確です。これを編集してより権威あるトーンで話すことが考えられます。 –

関連する問題