シェル入門:seqとxargsを利用した並列処理

スポンサーリンク
シェル入門:seqとxargsを利用した並列処理 ノウハウ
シェル入門:seqとxargsを利用した並列処理
この記事は約6分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、seqとxargsを利用した並列処理をしたときの方法についてご紹介します。

スポンサーリンク

背景

同時に同じ処理を実行する場面があり、seqとxargsを利用した並列処理を実施したので、そのときの処理内容を備忘として残しました。

実施環境の用意

下記のファイルを用意しました。proc.shに処理を記載しています。

└── proc.sh

proc.sh

#!/usr/bin/env bash

now=$(date "+%Y%m%d%W_%H%M%S")

sh_name=$(basename "$0")

arg01=$1

log_dir=${sh_name%.sh}/${now}

[ ! -e "${log_dir}" ] && mkdir -p "${log_dir}"

{
  echo now : "$now"
  echo log : "$log_dir"
  echo sh  : "$sh_name"
  echo seq : "$arg01"
} > "${log_dir}/${arg01}.log"

動作確認

下記のコマンドを実行します。

seq 10 | xargs -P $(nproc) -I{} -t sh -c "bash proc.sh {}" 

データ確認

下記のコマンドを実行します。

tree proc

下記のようにデータがあれば、構築成功です。

% tree proc 
proc
└── 2023082734_131316
    ├── 1.log
    ├── 10.log
    ├── 2.log
    ├── 3.log
    ├── 4.log
    ├── 5.log
    ├── 6.log
    ├── 7.log
    ├── 8.log
    └── 9.log

解説

proc.sh

このスクリプトは、Bashシェルスクリプトで書かれており、主に次の処理を行います。

  1. 現在の日時情報とスクリプトの情報を収集して変数に格納します。
  2. ログディレクトリを作成します(存在しない場合のみ)。
  3. 変数に収集した情報を書き込んだログファイルを生成します。

スクリプトの各行を詳しく説明します:

  1. #!/usr/bin/env bash: この行は、スクリプトがBashシェルで実行されることを示しています。
  2. now=$(date "+%Y%m%d%W_%H%M%S"): dateコマンドを使用して現在の日時情報を取得し、指定されたフォーマットに従って整形して変数nowに格納します。ここでは年月日と週番号、および時分秒が含まれるフォーマットが使用されています。
  3. sh_name=$(basename "$0"): 変数sh_nameには、スクリプトのファイル名(拡張子を含まない)が格納されます。$0はスクリプト自体へのパスを示す特殊な変数です。basenameコマンドはパスからファイル名を取得します。
  4. arg01=$1: 変数arg01には、スクリプト実行時に渡された第1引数(コマンドライン引数)が格納されます。
  5. log_dir=${sh_name%.sh}/${now}: log_dir変数には、ログディレクトリのパスが格納されます。このパスは、スクリプトのファイル名から拡張子 .sh を取り除いたものと、先ほど取得した日時情報を連結して生成されます。
  6. [ ! -e "${log_dir}" ] && mkdir -p "${log_dir}": ログディレクトリが存在しない場合、この行はそのディレクトリを作成します。[ ! -e "${log_dir}" ]は、ファイルやディレクトリが存在しない場合に真となる条件式です。&&は前のコマンドが成功した場合にのみ、次のコマンドを実行するための論理演算子です。mkdir -p "${log_dir}"はディレクトリを再帰的に作成するコマンドです。
  7. echo now : "$now"などの行: これらの行は、各情報をログファイルに書き込むためのコマンドです。{}内に含まれるコマンドは、まとめて1つのファイルにリダイレクトされます。> "${log_dir}/${arg01}.log"は、まとめたコマンドの出力をログファイルに書き込むためのリダイレクトです。

最終的に、このスクリプトは、ログファイルに次の情報を記録します:

  • 現在の日時情報
  • 生成されたログディレクトリのパス
  • 実行中のスクリプトファイルの名前
  • スクリプト実行時に渡された第1引数

これによって、スクリプトの実行ごとに異なる日時のログファイルが作成され、実行時の情報が記録されます。

seq 10 | xargs -P $(nproc) -I{} -t sh -c “bash proc.sh {}”

このコマンドは、Linuxのシェル環境で動作するコマンドラインのパイプラインです。各部分を解説します。

  1. seq 10: これは、1から10までの整数を生成するコマンドです。seqコマンドは指定された範囲の整数を順に出力します。
  2. |: パイプ演算子で、前のコマンドの出力を次のコマンドの入力として渡します。
  3. xargs -P $(nproc) -I{} -t sh -c "bash proc.sh {}":
    • xargs: 一連の引数を受け取り、それらを別のコマンドに渡すためのコマンドです。
    • -P $(nproc): 並列実行のためのオプションです。nprocコマンドはシステムの利用可能なプロセッサ数を返し、それを使って並列実行の数を指定しています。
    • -I{}: 渡された引数を後続のコマンドの中で {} に置換します。
    • -t: 実行されるコマンドを表示します。
    • sh -c "bash proc.sh {}": 渡された引数を使って、新しいシェルスクリプトを実行します。proc.shというスクリプトを実行し、引数を渡します。

総合すると、このコマンドは以下のことを行います:

  1. seq 10によって1から10までの整数が生成されます。
  2. xargsはそれぞれの整数を並列で処理するため、nprocで取得したプロセッサ数だけの並列実行を行います。
  3. 各整数が -t sh -c "bash proc.sh {}" として渡され、proc.shというスクリプトがそれぞれの整数を引数として実行されます。

つまり、このコマンドは proc.sh というスクリプトを、1から10までの整数を並列で処理しながら実行するものです。

おわりに

今日は、seqとxargsを利用した並列処理をしたときの方法についてご紹介しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました