sleep / seq
| 対応: | sleep | 全Linux |
|---|---|---|
| macOS(2001 Cheetah) | ||
| Bash 1.0(1989) | ||
| seq | 全Linux | |
| macOS(2005 Tiger) | ||
| Bash 1.0(1989) |
『sleep』は指定した時間だけスクリプトの実行を止めるコマンドです。『seq』は連番を生成するコマンドで、ループ処理や数値リストの生成に使います。どちらもシェルスクリプトでよく使うユーティリティです。
構文
『sleep』は数値と単位を指定します。単位を省略した場合は秒数として扱われます。
sleep 秒数 sleep 数値[s|m|h|d]
『seq』は最大値だけ指定する形式、開始と最大値を指定する形式、増分を指定する形式の3通りがあります。
seq 最大値 seq 開始 最大値 seq 開始 増分 最大値
sleep のオプション一覧
| 指定方法 | 説明 |
|---|---|
| sleep 5 | 5秒待機します。単位なしは秒です。 |
| sleep 0.5 | 0.5秒(500ミリ秒)待機します。macOS 標準の sleep は小数非対応(後述)。 |
| sleep 1m | 1分(60秒)待機します。 |
| sleep 1h | 1時間待機します。 |
| sleep 1d | 1日(24時間)待機します。 |
seq のオプション一覧
| オプション | 説明 |
|---|---|
| -w | ゼロ埋めして桁数を揃えます(01, 02, ... 10)。 |
| -s 文字列 | 区切り文字を指定します。デフォルトは改行です。 |
| -f フォーマット | printf 形式の書式を指定します(例: %05g)。 |
サンプルコード
『sleep』の基本的な使い方です。神室町の巡回スクリプトで、処理と処理の間に待機を入れる例です。
echo "神室町北エリアを確認中..." sleep 3 echo "神室町南エリアを確認中..." 神室町北エリアを確認中... 神室町南エリアを確認中...
分・時間単位での待機です。
sleep 1m && echo "1分後に再確認します" sleep 2h && echo "2時間後に再確認します"
『seq』の基本的な使い方です。引数が1つの場合は 1 から指定値までの連番を生成します。
seq 5 1 2 3 4 5
開始値と終了値を指定する形式です。
seq 3 7 3 4 5 6 7
増分を指定する形式です(開始 増分 終了の順)。
seq 1 2 10 1 3 5 7 9
『-w』オプションでゼロ埋めします。ファイル名やディレクトリ名の連番に使いやすい形式になります。
seq -w 1 10 01 02 03 04 05 06 07 08 09 10
『-s』オプションで区切り文字を指定します。スペース区切りで1行に出力する例です。
seq -s " " 1 5 1 2 3 4 5
『seq』を使った for ループです。構成員ログを5件分処理する例です。
clan_members.sh
#!/bin/bash
for i in $(seq 1 5); do
echo "clan_member_${i}.txt を処理中"
done
実行するコマンドは次の通りです。
bash clan_members.sh clan_member_1.txt を処理中 clan_member_2.txt を処理中 clan_member_3.txt を処理中 clan_member_4.txt を処理中 clan_member_5.txt を処理中
API の呼び出しなど失敗する可能性のある処理を、間隔を空けて繰り返すリトライ処理の例です。最大5回試みて、成功すればループを抜けます。
kamurocho_patrol.sh
#!/bin/bash
MAX_RETRY=5
INTERVAL=10
SUCCESS=0
for i in $(seq 1 $MAX_RETRY); do
echo "[$i/$MAX_RETRY] サーバーへ接続中..."
if curl -sf http://192.168.1.1/status > /dev/null; then
echo "接続成功"
SUCCESS=1
break
fi
echo "接続失敗。${INTERVAL}秒後にリトライします"
sleep $INTERVAL
done
if [ "$SUCCESS" -eq 0 ]; then
echo "最大リトライ回数に達しました" >&2
exit 1
fi
ゼロ埋め連番でログファイルをまとめて生成する例です。バトルログをセッション番号付きで作成します。
battle_log.sh
#!/bin/bash
for i in $(seq -w 1 10); do
touch "battle_log_${i}.txt"
echo "battle_log_${i}.txt を作成しました"
done
実行するコマンドは次の通りです。
bash battle_log.sh battle_log_01.txt を作成しました battle_log_02.txt を作成しました battle_log_03.txt を作成しました battle_log_04.txt を作成しました battle_log_05.txt を作成しました battle_log_06.txt を作成しました battle_log_07.txt を作成しました battle_log_08.txt を作成しました battle_log_09.txt を作成しました battle_log_10.txt を作成しました
ブレース展開との比較
Bash には『{1..10}』というブレース展開があり、seq と同様に連番を生成できます。外部コマンドを呼び出さないため動作が速く、シンプルな連番には好んで使われます。
echo {1..5}
1 2 3 4 5
実行するコマンドは次の通りです。
for i in {1..5}; do echo "member_${i}"; done
member_1
member_2
member_3
member_4
member_5
ただし、ブレース展開には 変数を使えない という制限があります。
MAX=5
for i in {1..$MAX}; do echo $i; done
{1..5}
変数を終端に使いたい場合は seq を使います。
MAX=5 for i in $(seq 1 $MAX); do echo $i; done 1 2 3 4 5
| seq | {1..N} ブレース展開 | |
|---|---|---|
| 変数の使用 | 可能 | 不可(固定値のみ) |
| 増分指定 | 可能(seq 1 2 10) | 可能({1..10..2}) |
| ゼロ埋め | 可能(-w オプション) | 可能({01..10}) |
| 外部コマンド | 必要 | 不要(Bash 組み込み) |
| 小数の連番 | 可能(seq 0.1 0.1 1.0) | 不可 |
概要
『sleep』は Bash 組み込みコマンドではなく外部コマンド(通常 /bin/sleep)です。単位なしで渡した数値は秒数として扱われます。GNU coreutils の sleep は s(秒)・m(分)・h(時)・d(日)の単位をサポートしており、複数指定の合算(sleep 1m 30s)も可能です。
『seq』も外部コマンド(通常 /usr/bin/seq)です。引数が1つのときは「1 から N まで」、2つのときは「開始 から 終了 まで」、3つのときは「開始 増分 終了」と解釈されます。デフォルトの区切りは改行ですが、-s オプションで変更できます。
リトライ処理では 指数バックオフ(待機時間を試行ごとに倍にする)が使われることがあります。sleep $((INTERVAL * i)) のように算術展開と組み合わせると実装できます。
よくあるミス
よくあるミス1: macOS の sleep は小数非対応
Linux(GNU coreutils)の sleep は小数秒に対応していますが、macOS 標準の sleep(BSD sleep)は整数秒しか受け付けません。小数を渡すとエラーになります。
sleep 0.5 illegal time interval -- 0.5
macOS で小数秒の sleep を使いたい場合は、Homebrew で GNU coreutils をインストールして gsleep を使います。
brew install coreutils gsleep 0.5 && echo "0.5秒待機完了" 0.5秒待機完了
スクリプトをmacOS と Linux 両方で動かしたい場合は、gsleep が存在すればそちらを使い、なければ sleep にフォールバックする書き方が使われます。
cross_platform_sleep.sh
#!/bin/bash
SLEEP_CMD="sleep"
if command -v gsleep > /dev/null 2>&1; then
SLEEP_CMD="gsleep"
fi
$SLEEP_CMD 0.5
echo "待機完了"
よくあるミス2: ブレース展開で変数を使おうとする
ブレース展開はシェルの展開フェーズが変数置換より先に行われるため、{1..$MAX} のように変数を使ってもそのままリテラル文字列として出力されます。
MAX=5
echo {1..$MAX}
{1..5}
変数を使って動的に終端を決めたい場合は seq か eval を使います。eval にはセキュリティリスクがあるため、seq を選ぶ書き方がよく見られます。
MAX=5 for i in $(seq 1 $MAX); do echo $i; done 1 2 3 4 5
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。