xargsで個別ファイルにリダイレクト

シミュレーションを並列実行させるために今までは forと&(アンパサンド)を用いていた。

並列実行数を指定できると聞いて(xargs -P が激しく便利なのでメモ – 新生おともだち研究会)xargsの使い方を調べていたが、乱数のシード毎に出力ファイル(リダイレクト)を分ける方法で詰まった。

【実現したいこと】
xargs は個別ファイルへ書き出すリダイレクトのパイプが使えない → for を使う – ブックマクロ開発にに書いてあることと同様のこと。

シェルスクリプト(bash)により、乱数の種(0~9)をそれぞれ引数にとるシミュレータを実行し、結果をoutput_0.txt ~ output_9.txtにリダイレクトする。

余談だが、標準出力をリダイレクトさせるという、出力の方法を見直したほうが良い気がしたので、それはまた今度やる。

【実現方法】

xargsの引数としてコマンド(シミュレータの実行ファイル)を渡すのではなく、シミュレータを実行するシェル関数を渡すようにする。

つまり、余分なワンクッションを入れる。

【run_sim.sh】


#!/bin/bash
####################
## リダイレクト先に「xargsにパイプを経由して渡した引数を含むファイル名」を設定するためのワンクッション
func()
{
## コマンド及び引数の並び
# func <seed>
## 時間がかかる処理
sleep 3s
## シミュレータが結果を出力する代わりにechoでテスト
echo "Simulation $1 finished !" > output_$1.txt
}
## xargsからfuncが利用できるようにexport
export -f func
## 引数(乱数の種)を0から9まで変えながら、4つまで並列に処理する
seq 0 9 | xargs -t -n1 -P4 -I % bash -c "func %"
## 以下のコマンドでは、個別ファイルが作成されない
## リダイレクト記号">"より右はxargsの影響外である
# seq 0 9 | xargs -t -n1 -P4 -I % echo "Simulation % finished" > output_%.txt

view raw

run_sim.sh

hosted with ❤ by GitHub

【xargs】
-t : 実行するコマンドを標準出力に表示するオプション(テスト用)
-n1 : パイプで渡された引数群を1つずつで区切る。 -n2なら2つずつ区切る。
-P4 : 4つまで並列に処理する。
-I % : パイプで渡された引数を、%で指定した部分に挿入する
(参考)xargsメモ – ぱせらんメモ

【bash -c】
対話モードを起動せずに、単純に引数のコマンドを実行。
(参考)xargsにbashのfunctionを渡す方法 – Weballergy

紹介 mkacky
情報工学系の大学院生(D2/2013年現在)

コメントを残す