※当サイトの記事には、広告・プロモーションが含まれます。

Linuxの標準の機能で処理の進捗(progress)表示を実現したい

news.mynavi.jp

OpenAIの理事会が17日に、「理事会とのコミュニケーションで一貫して率直さを欠いていた」という理由で、アルトマン氏に突如解任を言い渡した。

アルトマン氏がOpenAIのCEOに復帰、理事会を再編し解任騒動の経緯を調査 | TECH+(テックプラス)

その後、Microsoftがアルトマン氏の受け入れを表明。OpenAIでは、アルトマン氏の解任を決めた理事会に対する反発が強く、最終的に9割を超える社員が理事の辞任を求める書簡に署名。要求が受け入れられない場合、アルトマン氏がMicrosoftで率いるAIリサーチ部門に加わる可能性を示していた。米報道によると、理事会から暫定CEOに指名されたエメット・シア氏(Twitchの元CEO)も、アルトマン氏の解任の正当性を裏付ける証拠を示すよう理事会に求めていた。

アルトマン氏がOpenAIのCEOに復帰、理事会を再編し解任騒動の経緯を調査 | TECH+(テックプラス)

⇧ 社員の9割から不信感を持たれる時点で、理事としての責務を全うしていないことを物語ってますな。

「理事会とのコミュニケーションで一貫して率直さを欠いていた」』という言葉が特大ブーメランとなってる皮肉。

調査は難しいとは思いますが、公平性を持って経緯を明らかにして欲しいところですね。

進捗(progress)表示を実現するライブラリはインストールが必要という現実

Linuxで処理の状態を確認したい、となった場合に、進捗(progress)が分かるような出力がされると、親切ですと。

で、

wonderwall.hatenablog.com

⇧ 上記サイト様によりますと、

  • progress
  • pv

というライブラリが存在するそうな。

ただし、どちらも、インストールが必要とのことなので、Linuxの標準の機能で処理の進捗(progress)表示を実現することはできませんと。

Linuxの標準の機能で処理の進捗(progress)表示を実現したい

ネットの情報を漁っていたところ、

dampgblog.hinohikari291.com

シェルでコマンドをパイプで繋いで実行した場合、順番に実行されるのではなく、並列実行されると本に書かれてあったので、軽く検証した。

パイプで連結したコマンドは並列実行される | damのブログラミング雑記ブログ

パイプを使うことで子プロセスが生じ並列処理されたのだろう。

パイプで連結したコマンドは並列実行される | damのブログラミング雑記ブログ

⇧ 上記サイト様によりますと、処理をパイプで繋げると並列処理されるとありますと。

そして、bashであれば、

kawa0810.hateblo.jp

fumiyas.github.io

⇧ 上記サイト様によりますと、特別な変数で、パイプで繋がった各処理の終了ステータスが取得できますと。

とりあえず、

  1. 処理をパイプで繋げる
  2. 前の処理のプロセスIDを取得
  3. 次の処理(進捗を記録する)で前の処理のプロセスIDの状態をチェックし続ける
  4. 前の処理のプロセスIDが無くなったタイミングで、次の処理(進捗を記録する)を終了させる

を組み合わせることで、進捗(progress)表示が実現できそうかと。

進捗(progress)表示を試してみる

というわけで、試してみました。

動作確認の環境は、「WSL 2(Windows Subsystem for Linux 2)」の「Ubuntu 22.04.2 LTS (GNU/Linux 5.15.133.1-microsoft-standard-WSL2 x86_64)」です。

むちゃくちゃ、泥沼にハマって、勤労感謝の日に徹夜するという...

休日を返して欲しい...

ちなみに、IT業界の経験が長い方から、業務に関わる学習は自己研鑽に含まれないという発言を聞いて、学習のモチベーションがだだ下がり中ですわ...。

脱線しましたが、結果のソースコードを掲載。

■/home/ts0818/work/test_progress/test_progress.sh

#!/bin/bash
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
# ■  @title テスト用処理
# ■  @description
# ■    test_progress.sh
# ■    進捗を記録する処理を検証するための処理
# ■  @author ts0818
# ■  @version 1.0 2023-11-23
# ■  @since GNU/Linux 5.15.133.1-microsoft-standard-WSL2 x86_64
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

# 処理開始日時
START_DATE_TIME=$(date +"%Y-%m-%d %H:%M:%S.%3N")
echo "[${START_DATE_TIME}][start]test_progress.sh"

# 開始時間
start=0

# 終了時間
end=10

# 終了時間になるまで繰り返し
while [[ $start -le $end ]];
do
  # 1秒スリーブ
  sleep 1
  
  # 開始時間に、1加算(1秒経過を表現)
  start=$(($start+1))

done

# 処理終了日時
FINISH_DATE_TIME=$(date +"%Y-%m-%d %H:%M:%S.%3N")
echo "[${FINISH_DATE_TIME}][finished]test_progress.sh"

■/home/ts0818/work/test_progress/progress_echo.sh

#!/bin/bash
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
# ■  @title 進捗記録処理
# ■  @description
# ■    progress_echo.sh
# ■    進捗を記録する処理を実行する関数
# ■  @author ts0818
# ■  @version 1.0 2023-11-23
# ■  @since GNU/Linux 5.15.133.1-microsoft-standard-WSL2 x86_64
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

function progress_echo() {
  target_pid="$1"
  local _processing=""
  # 経過時間用
  local start=0
  # タイムアウト
  local time_out=120
  
  echo 'args ${target_pid}'"${target_pid}"
  
  # 対象の処理のプロセスが終了するまで繰り返し
  while [ -n "${target_pid}" ];
  do
    # プロセスが終了していないか確認
    if [ -n "${target_pid}" ]; then
      target_pid=$(ps -p "${target_pid}" | awk 'NR!=1{print $1}')
    fi
    
    progress="..."
    #echo 'update ${target_pid}'"${target_pid}"

    LF=$'\n'
    
    LENGTH_LIMIT_ONE_LINE=32

    _processing+="${progress}"
    
    if [[ "${#_processing}" -eq "${#progress}" ]]; then
      _processing+="${LF}${_processing}"
      printf "${_processing}";
    fi

    if [[ "${#_processing}" -gt "${LENGTH_LIMIT_ONE_LINE}" ]]; then
      _processing=""
    
    else
      printf "${_processing}";
    
    fi

    sleep 1
    
    # 開始時間に、1加算(1秒経過を表現)
    start=$(($start+1))
    
    # 処理の経過時間が、タイムアウトの時間を超過した場合
    if [ "${start}" -gt "${time_out}" ]; then
      echo "timeout. Finished in the middle of progress_echo.sh"
      繰り返しを抜ける
      break;
    fi

  done

}

■/home/ts0818/work/test_progress/test_main.sh

#!/bin/bash
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
# ■  @title メイン処理
# ■  @description
# ■    test_main.sh
# ■    進捗を記録する処理を実行する
# ■  @author ts0818
# ■  @version 1.0 2023-11-23
# ■  @since GNU/Linux 5.15.133.1-microsoft-standard-WSL2 x86_64
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

# 外部のシェルスクリプトのファイルを読み込み
source ./progress_echo.sh

# 処理開始日時
START_DATE_TIME=$(date +"%Y-%m-%d %H:%M:%S.%3N")
echo "[${START_DATE_TIME}][start]main.sh"

# 進捗を記録するファイル
RESULT_PROGRESS_TXT=result_progress.txt

echo "before start test_progress.sh and progress_echo.sh"

# 進捗を記録したい処理の開始し、進捗を記録する
bash test_progress.sh | 
  ps axf | grep "test_progress" | grep -v grep | awk '{print $1}' | 
  { read pid; progress_echo "$pid"; } | tee -a "${RESULT_PROGRESS_TXT}"

echo "after finished test_progress.sh and progress_echo.sh"

# 処理終了日時
FINISH_DATE_TIME=$(date +"%Y-%m-%d %H:%M:%S.%3N")
echo "[${FINISH_DATE_TIME}][finished]main.sh"

⇧ で、実行すると、

⇧ 表示の改行とかは要調整ですが、別プロセスの処理に対しての進捗(progress)の状態っぽい出力を実施することができました。

自力で実現する場合、パーセンテージとかで処理の割合を出すのは無理そうですが、処理が終わるまで、「処理中」を意味するような出力を出し続けるってことは可能ってことですかね。

ライブラリとか使えば、お手軽に実現できるのかもしれんのですが...

毎度モヤモヤ感が半端ない...

今回はこのへんで。