2016-10-10 1 views
1

スクリプトは、ファイルを提出し、提出したサンプル(#task.csvバッシュ複数のcURLの要求を発行し

#file_submitter.sh 

#!/bin/bash 

for i in $(find $1 -type f);do 
     task_id="$(curl -s -F [email protected]$i http://X.X.X.X:8080/api/abc/v1/upload &)" 
     echo "$task_id" >> task.csv 
done 

実行方法の後、APIサービスのリターンを提出する "TASK_ID":

$./submitter.sh /home/files/ 

結果: (761 & 762は、APIサービスから提出されたサンプルのtask_idです)

#task.csv 

{"task_url": "http://X.X.X.X:8080/api/abc/v1/task/761"} 
{"task_url": "http://X.X.X.X:8080/api/abc/v1/task/762"} 

ファイルをアップロードするディレクトリ内のすべてのファイルを見つけるために、フォルダパス全体(find $1 -type f)を指定しています。今、 "&"演算子を使用して、APIサービス(stdout)から 'task_id'を生成するフォルダからファイルをサブミット/アップロードします。'task_id'(stdout)に'task.csv'を格納します。しかし、"&"でファイルをアップロードし、"&"なしでアップロードする時間は同じです。提出を並行/より速く行う方法はありますか?何か提案してください?

答えて

1

あなたは-Pオプションでxargsを使用することができます。これは、並行して5つのcurlプロセスを起動することによって、総実行時間を短縮します

find "$1" -type f -print0 | 
xargs -0 -P 5 -I{} curl -s -F file='@{}' http://X.X.X.X:8080/api/abc/v1/upload >> task.csv 

+0

xargsを使うと、パス './submitter.sh/home/files/pdf/'を与える​​と、結果は1つだけ返されます。たとえば、フォルダpdfに5つのファイルがあるとします。その結果は約5つのtask_idsでなければなりませんか? – Arun

+0

更新された回答を今すぐお試しください。 – anubhava

+1

それはうまく動作します!ありがとう – Arun

1

コマンド内のコマンド置換$()は、サブシェルで実行されます。ここでは、親シェルではなくそのサブシェルのバックグラウンドでcurlコマンドを送信しています。

は、コマンド置換を取り除く、とだけやるなさい:

curl -s -F [email protected]$i http://X.X.X.X:8080/api/abc/v1/upload >task.csv & 
+0

'curl'コマンドの後に' task.cv'を実行します。 – Inian

1

あなたはコマンド置換($())の内部を並列化するためにシェルを言っています。それはあなたが望むことをするつもりはありません。代わりにこれを試してみてください:

#!/bin/bash 

for i in $(find $1 -type f);do 
     curl -s -F [email protected]$i http://X.X.X.X:8080/api/abc/v1/upload & 
done > task.csv 
#uncomment next line if you want the script to pause until the last curl is done 
#wait 

これは、バックグラウンドにcurlを置き、task.csvにその出力を保存します。

+0

ありがとうエリック。 'task_id'はマシンのタスク/プロセス(echo $!)ではありません。これは、サンプルが提出されたときにAPIサービスによって自動生成されます。質問 – Arun

+1

を更新しました。アップデートを反映する答えを編集しました – Eric

+0

完璧に動作します。アンパサンド(&)を使用すると、どれくらいのプロセスが起動しますか。その結果、私は非常に多くのエラーメッセージを見なければなりません。一度に送信するリクエストの数のために。私たちが送信するクエリを制限できますか? – Arun

1

anubhavaは-Pオプションでxargsを使用することを提案:

find "$1" -type f -print0 | 
xargs -0 -P 5 curl -s -F [email protected] http://X.X.X.X:8080/api/abc/v1/upload >> task.csv 

はしかし、並行して同じファイルに追加することは一般的に悪い考えです:あなたは本当にOSのこのバージョンは、出力をバッファリングする方法について多くのことを知っておく必要がありますそれが安全であるために。この例では、なぜ示していますsize=10

#!/bin/bash 

size=3000 

myfile=/tmp/myfile$$ 
rm $myfile 

echo {a..z} | xargs -P26 -n1 perl -e 'print ((shift)x'$size')' >> $myfile 

cat $myfile | perl -ne 'for(split//,$_){ 
    if($_ eq $l) { 
    $c++ 
    } else { 
    /\n/ and next; 
    print $l,1+$c," "; $l=$_; $c=0; 
    } 
}' 
echo 

をあなたは常に(順序が異なる場合があります)を取得します:

1 d10 i10 c10 n10 h10 x10 l10 b10 u10 w10 t10 o10 y10 z10 p10 j10 q10 s10 v10 r10 k10 e10 m10 f10 g10 
ファイルが10 Dのように、私は10件のCさんが続いています10続くとを含有していることを意味

を。私。 26のジョブからの出力が混在することはありません。

しかしsize=30000に変更して、あなたのようなものを得る:ように

1 c30000 d30000 l8192 g8192 t8192 g8192 t8192 g8192 t8192 g5424 t5424 a8192 i16384 s8192 i8192 s8192 i5424 s13616 f16384 k24576 p24576 n8192 l8192 n8192 l13616 n13616 r16384 u8192 r8192 u8192 r5424 u8192 o16384 b8192 j8192 b8192 j8192 b8192 j8192 b5424 a21808 v8192 o8192 v8192 o5424 v13616 j5424 u5424 h16384 p5424 h13616 x8192 m8192 k5424 m8192 q8192 f8192 m8192 f5424 m5424 q21808 x21808 y30000 e30000 w30000 

まず30KのCさん、そして30K D'sの、そして8K L'sの、そして8Kグラムの、8KのTさん、その後、別の8Kグラムの、およびを。私。 26のアウトプットが混在していた。非常に悪い。

そのため、同じファイルに並行して追加することについてアドバイスします。競合状態の危険性があり、しばしばこれを避けることができます。この競合状態に対するGNUパラレルガードので、あなたは単に、代わりにxargsののGNUパラレルを使用することができますあなたの場合は

:「!$」 `エコー、起動したプロセスのTASK_IDを保存するには

find "$1" -type f -print0 | 
parallel -0 -P 5 curl -s -F [email protected]{} http://X.X.X.X:8080/api/abc/v1/upload >> task.csv 
関連する問題