UNIX/Linuxの部屋 コマンド:sleep

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




コマンド sleep 指定秒数だけプロセスの動作を止める このエントリーをはてなブックマークに追加

UNIX/Linux における sleep コマンドは、指定された秒数だけ、そのプロセスの動作を止めるコマンドである。ずっと処理を実行し続けていると負荷がかかるため、適当な時間ウェイトを入れる場合に使う。



sleep コマンドの基本的な使い方
sleep コマンドの引数に sleep させたい秒数を指定する。
% sleep 3
% ← このプロンプトが表示されるまで 3秒かかる
5分間 (300秒) 動作停止するには下記のようにする。
% sleep 300

sleep コマンドの suffix 指定
Linux で使われている GNU の sleep コマンドでは、適切な suffix を指定することにより分・時間・日単位で sleep 秒数を指定できる。
% sleep 1s (1秒 sleep)
% sleep 2m (2分 sleep)
% sleep 3h (3時間 sleep)
% sleep 4d (4日 sleep)
% sleep 3h 20m (3時間と20分 sleep)
→ 複数組み合わせることもできる
% sleep 1 3 (1+3で、4秒 sleep)
→ こういうこともできるようだ

sleep コマンドの様々な使い方
たとえば巨大なファイルを tar や gzip 等で操作していて、毎秒の進行状況を知りたい場合は、sh・bash なら
% while true; do ls -l foo.tar ; sleep 1 ; done
csh・tcsh なら
% while (1)
while? ls -l foo.tar
while? sleep 1
while? end
などとする。

telnet コマンドで自動ログインして任意コマンドを実行したい場合など、
% ( echo username ; echo password ; echo ls ) | telnet foo.bar.com
と書いてしまうと echo コマンドがすぐに終了してしまい、telnet は標準入力が閉じられてしまうので Broken Pipe が発生し、うまくいかない。そのようなときは
% ( echo username ; echo password ; echo ls ; sleep 3 ) | telnet foo.bar.com
などとする。

また、受信側の実装によるが、短時間に echo を出力するとひとつのパケットとして送信されてしまい、通信に失敗することもある。その場合、下記のように echo 実行の間に少しずつ sleep させる手もある。
% ( echo USER username ; sleep 1 ; echo PASS password ; sleep 1 ; echo LIST ; sleep 3 ) | telnet foo.bar.com pop3

また、30秒単位で cron からプログラムを実行するには crontab に
* * * * * date & sleep 30 ; date
などと指定するとよい。

指定した時間にあるコマンドを実行したい場合は、普通 at や cron を使う手もある。しかし、これまでコマンドライン上で動かしていたプログラムを いきなり cron 上で動かそうとしても、環境変数などの問題ですんなりと動くとは限らない。そういうときは
% sleep 36000 ; command
とすれば、きっちり 10時間後にコマンドが実行される。とにかく数時間後に一度だけ動けばよい、という場合はお勧め。ちなみにカップラーメンにお湯を入れた後に打つコマンドは
% sleep 180 ; printf "\a"
である。

小数指定・ミリ秒指定で sleep
*BSD や、新しめの Linux のように、
% sleep 3.45
などと小数点以下の秒数まで sleep できる実装もあるが、POSIX 的には整数のみを受け付けるのが正しい。もしお使いの Linux で小数指定ができない場合、RedHat 系 Linux では usleep コマンドが用意されているようなので試してみてほしい。
また、Ubuntu では sleepenh コマンドで小数指定ができるらしい。

sleep コマンドの負荷について
sleep コマンドは内部的にはシステムコール nanosleep(2) を呼ぶが、その時間の間カーネルのスケジューラに割当てがされないようになるので、負荷はかからない。

逆に、下記のように無限ループをしてしまうと、CPU 使用率が 100% 近くになり、ロードアベレージがちょうど 1 程度上がり、マシンに多大な負荷をかけてしまうことになる。
# sh や bash での無限ループ
while true; do true; done

sleep・usleep 等で小数指定ができない古めの OS の場合、下記のように Perl + select(2) を使うとよいだろう。select(2) は I/O が入出力可能になるまで待つシステムコールだが、その際タイムアウト秒数を小数で指定できるため、下記は sleep 0.5 と同じ結果となる。
% perl -e 'select undef, undef, undef, 0.5'
なお、Perl でなくてもよいが、Python などだと import 文が必要だったりしてちょっと面倒である。

ランダム秒数で sleep
sh・bash 等のシェルスクリプトでランダムに sleep したい場合、下記のようにする。
while true; do
何かの処理
sec=`expr $RANDOM % 100` # 0〜99秒 のいずれか
sleep $sec
done
その他の方法は下記を参照のこと。

関連コマンド

システムコール・ライブラリ関数は sleep(3)・usleep(3)・nanosleep(2) を参照のこと。
>> Solaris10オンラインマニュアル(man) Solaris10 sleep(1)
>> FreeBSDオンラインマニュアル(man) FreeBSD sleep(1)
>> Linuxオンラインマニュアル(man) Linux sleep(3)
>> Linuxオンラインマニュアル(man) Linux sleep(1)

関数 sleep 指定秒数の間、動作を止める このエントリーをはてなブックマークに追加

#include <unistd.h>
sleep(秒数);