時間のかかる処理を実行中に、「この次はこれを実行したい」となることはあります。
そんなとき、素直に処理が終わるのを待つと、集中や睡眠が阻害されます。
「現在の処理の終了が見込まれる時刻に開始」などといったスクリプトを書く手はありますが、見込み時刻の算出が面倒なこともあるし、安全を見込むと時間のムダが生じます。また、さらにその次に実行したい処理が出てきたときに何時に開始すべきか混乱してきます。
最初からキューを用意して、そこから随時タスク指示ファイルを取り出して実行させるようにしておけば、これらの問題は起きません。「この次はこれを実行したい」となるたびにキューに指示ファイルを放り込むだけで OK です。
方法
ディレクトリ構成のイメージは以下です。キュー root/20260504/queue にタスク指示ファイルを置き、ここにファイルがある限り、今日の作業場所 root/20260504 に取り出して実行させるものとします (キューがサブディレクトリである必要はありませんが)。
root/
└─ 20260504/ # 今日の作業場所
├─ queue/ # キュー
│ ├─ task_config_02.toml
│ ├─ task_config_03.toml
│ └─ task_config_04.toml
├─ task_config_00.toml
└─ task_config_01.toml
そのようなシェルスクリプトの例は以下になります。タスク指示ファイルの拡張子が .toml である想定です。異なる場合は変更してください。
#!/usr/bin/env bash
sub_dir="20260504"
queue_dir="${sub_dir}/queue"
while true; do
target="$(find "$queue_dir" -maxdepth 1 -type f -name '*.toml' | sort | head -n 1)"
[ -n "$target" ] || { echo "キューが空になりました"; break; }
moved="${sub_dir}/$(basename "$target")"
[ -f "$moved" ] && { echo "同名の指示ファイルが作業場所にあります"; continue; }
mv "$target" "$moved"
echo "$moved"
# ここに $moved に基づく処理を実行するコマンドを記入
done
[備考] 先入れ先出しにする
上記のスクリプトはタスク指示ファイルをファイル名昇順に取り出します。
なので、普段は 3001.toml 3002.toml … のようなファイル名でキューに追加し、割り込みしたいタスクは 2001.toml、さらに割り込みしたいタスクは 1001.toml とし、逆に劣後するタスクは 4001.toml にするような運用ができます。
そうではなく、先に入れた (更新時刻が古い) ファイルを先に取り出してほしい場合は、タスク指示ファイルを find する箇所を以下のように変更してください。最終更新時刻 (UNIX秒) をファイル名の前に付けてその昇順でソートした後、ファイル名部分を取り出します。
# toml="$(find "$queue_dir" -maxdepth 1 -type f -name '*.toml' | sort | head -n 1)"
toml="$(
find "$queue_dir" -maxdepth 1 -type f -name '*.toml' -printf '%T@ %p\n' |
sort -n | head -n 1 | cut -d' ' -f2-
)"