3

をバックグラウンド化は、それが依頼する時が来ました次の組み合わせを行うことを試みる:Bashのパラメータ展開、間接参照、そして数時間、この問題で苦労してここに検索し、一致した解決策を考え出すために失敗した後

  • 超高速ではありませんコマンドを使用して、配列の値をループの配列
  • を作成します(値を取得するには、Webサーバーへのカール)、すべてのループをバックグラウンドで並列化して高速化します。各PIDを
  • 背景を「読み取り」の各ループと通常の配列、仲間に自分のPIDを取得経由でコマンドからそれにリダイレクト値に割り当てられた変数に配列の値の名前を設定
  • 関連する配列の値が連想配列になっているので、PIDに配列の値のキー=値の組があります
  • 各PIDが終了するのを待つために "wait"を使用するか、結合配列を参照して配列を0で終了できませんでした
  • 元の配列内のすべてのVAR名をエクスポートする必要があります。結果のエクスポートされたVAR /値を使用する別のbashスクリプトからこのスクリプトを入手しているので、現在関連付けられている値(curlコマンドの結果から)です。

"export var = $(command)"などの "export"ではなく "read"を使用している理由は、バックグラウンドで「wait」を使用するPID次のループのために、私は実際には(間違って) "エクスポート"コマンドのPIDを常に0にするので、エラーは検出されません。リダイレクトでreadを使用してVARの値(配列の名前から)とバックグラウンドを設定すると、実際にコマンドのPIDが取得され、 "wait"コマンドで次のループでエラーが検出されます。私は、コマンドが実際にリダイレクトコマンドは、その出力を送信する方法で、適切に配列名の値に変数を代入していないと思われる「読み」が実現除く

ので、基本的に、これは主に動作するように見える、その名前に置換VAR名を設定します。または、おそらくコマンドがちょうど完全に間違っているので、コマンドの結果をVAR名に正しくリダイレ​​クトしていないため、設定しようとしています。

私はカールを実行すると、それは何の価値があるのですか? Pythonコマンドを手作業で(値をプルしてからJSON出力を解析するために)、それは間違いなく成功しているので、動作していることを知っているので、出力結果をVAR名に送ることはできません。ここで

は、私が何をしようとしているの例です:親スクリプトで :子で

# Source the child script that has the functions I need 
source functions.sh 

# Create the array 
VALUES=(
VALUE_A 
VALUE_B 
VALUE_C 
) 

# Call the function sourced from the script above, which will use the above defined array 
function_getvalues 

(調達)スクリプト:問題は実行することread、ある

function_getvalues() 
{ 
    curl_pids=() 
    declare -A value_pids 
    for value in "${VALUES[@]}"; do 
    read ${value} < <(curl -f -s -X GET http://path/to/json/value | python3 -c "import sys, json; print(json.load(sys.stdin)['data']['value'])") & curl_pids+=($!) value_pids+=([$!]=${value}) 
    done 
    for pid in "${curl_pids[@]}"; do 
    wait "$pid" && echo "Successfully retrieved value ${value_pids[$pid]} from Webserver." || { echo "Something went wrong retrieving value ${value_pids[$pid]}, so we couldn't get the output data needed from Webserver. Exiting." ; exit 1 ; } 
    done 
} 
+0

私はechoコマンドを追加してvar(var名が配列からループされています)が何に設定されているかを確認しようとしましたが、それらは空白です。私は、もしそれらがreadコマンドで全く宣言されていない(つまり、代入が機能していない)、または書かれた私のreadリダイレクションのエラーがコマンドの出力をVARに送ることに失敗したそれを設定する名前。 –

+0

申し訳ありませんが、python json parseの後のcurlコマンドの出力は文字列です。 curl | pythonを手で実行すると、予想される出力が得られます。読み取りリダイレクトではありません。 –

+1

また、私はjqの代わりにpythonを使用しています。なぜなら、私はPythonにもっと慣れているからです。b)私は最小限の依存関係を保つために努力しています。 –

答えて

1

バックグラウンドでは、isn't connectedを標準で入力します。[details]はそれを無力にする方法をコメントで、この単純化され、実施例を考えてみましょう:

VALUES=(VALUE_A VALUE_B) 
for value in "${VALUES[@]}"; do 
    read ${value} < <(echo ${RANDOM}) # add "&" and it stops working 
done 
echo "VALUE_A=${VALUE_A}" 
echo "VALUE_B=${VALUE_B}" 

あなたはcoproc、またはread -u with automatic file descriptor allocationを使用してこれを行うことができるかもしれませんが、本当にこれは一時的なファイルのための仕事は次のとおりです。

tmpdir=$(mktemp -d) 

VALUES=(VALUE_A VALUE_B) 
for value in "${VALUES[@]}"; do 
    (sleep 1; echo ${RANDOM} > "${tmpdir}"/"${value}") & 
done 
for value in "${VALUES[@]}"; do 
    wait_file "${tmpdir}"/"${value}" && { 
     read -r ${value} < "${tmpdir}"/"${value}"; 
    } 
done 
echo "VALUE_A=${VALUE_A}" 
echo "VALUE_B=${VALUE_B}" 

rm -r "${tmpdir}" 

この例ではwait_file helperを使用していますが、OSに依存しない場合はinotifywaitを使用してください。

+0

興味深い解決策、感謝司教。読者が標準との接続を失うのは完全に意味があります。もともと私は 'export'コマンドを使用していたときに同じ懸念を抱いていました。私はこの解決策に1つのシワがあります:これを実行する開発者の多くは、OS X上にあり、mktempの動作が異なっていることを読んでいます。どんな洞察?私は確かにこれも研究することができます。 –

+0

はい、 'mktemp'に移植性の問題があります。解決方法については、https://unix.stackexchange.com/a/84980/50240 – bishop

+0

を参照してください。「mktemp -d」は、OS X(最新)とLinuxの両方で同じように動作することをテストできました。私たちの開発者が使用しているシステムなので、それは私のために十分であり、移植性があります。 –

関連する問題