web-dev-qa-db-ja.com

bashまたはkshで1ミリ秒間スリープする方法

sleepは非常に人気のあるコマンドで、1秒からスリープを開始できます。

# wait one second please 
sleep 1

しかし、0.1秒だけ待つ必要がある場合、または0.1〜1秒待つ必要がある場合の代替方法は何ですか。

  • 備考:LinuxまたはOS Xの場合sleep 0.XXXは正常に動作しますが、ソラリスではsleep 0.1またはsleep 0.01-不正な構文
142
yael

Bashには、端数秒をサポートする「ロード可能な」スリープがあり、外部コマンドのオーバーヘッドを排除します。

$ cd bash-3.2.48/examples/loadables
$ make sleep && mv sleep sleep.so
$ enable -f sleep.so sleep

次に:

$ which sleep
/usr/bin/sleep
$ builtin sleep
sleep: usage: sleep seconds[.fraction]
$ time (for f in `seq 1 10`; do builtin sleep 0.1; done)
real    0m1.000s
user    0m0.004s
sys     0m0.004s

欠点は、ローダブルがbashバイナリで提供されない可能性があるため、図のように自分でコンパイルする必要があります(ただし、Solarisでは上記のように単純である必要はありません)。

bash-4.4(2016年9月)以降、すべてのロード可能コンポーネントは、デフォルトでそれをサポートするプラットフォームにビルドおよびインストールされますが、別の共有オブジェクトファイル、および.soサフィックスなし。あなたのディストリビューション/ OSが何かクリエイティブなことをしない限り(悲しいことにRHEL/CentOS 8ビルドbash-4.4でロード可能な拡張機能を意図的に削除してを削除)、代わりに次のことができるはずです:

[ -z "$BASH_LOADABLES_PATH" ] &&
  BASH_LOADABLES_PATH=$(pkg-config bash --variable=loadablesdir 2>/dev/null)  
enable -f sleep sleep

(manページはBASH_LOADABLES_PATHが自動的に設定されることを示唆していますが、4.4.12の公式ディストリビューションではそうではありません。正しく設定されている場合、必要なのはenable -f filename commandnameのみです。)

それが適切でない場合、次に行う最も簡単なことは、GNU coreutilsからsleepをビルドまたは取得することです。これにより、必要な機能がサポートされます。POSIX sleep コマンドは最小限であり、古いバージョンのSolarisはそれだけを実装しています Solaris 11 sleepdoesは小数秒をサポートしています。

最後の手段として、Perl(または他のスクリプトを使用する必要があります)を使用して、インタプリタの初期化が目的のスリープ時間に匹敵する可能性があることに注意してください。

$ Perl -e "select(undef,undef,undef,0.1);"
$ echo "after 100" | tclsh
71
mr.spuratic

coreutilsからの sleep コマンドのドキュメントは次のように述べています:

歴史的なスリープの実装では、数値は整数である必要があり、サフィックスのない単一の引数のみを受け入れました。ただし、GNU sleepは任意の浮動小数点数を受け入れます。 浮動小数点 を参照してください。

したがって、sleep 0.1sleep 1.0e-1および同様の引数。

136
scai

Sleepは10進数を受け入れるため、次のように分解できます。

1/2秒

 sleep 0.5

1/100秒

sleep 0.01

ミリ秒の間は、

sleep 0.001
64
colealtdelete

これを試して精度を判断します。

    time sleep 0.5      # 500 milliseconds (1/2 of a second)
    time sleep 0.001    # 1 millisecond (1/1000 of a second)
    time sleep 1.0      # 1 second (1000 milliseconds)

mr.spuratic's solutioncoles's solution の組み合わせ。

12
dsrdakota

単にusleepを使用できます。パラメータとしてマイクロ秒(= 1e-6秒)がかかるため、1ミリ秒スリープするには、次のように入力します。

usleep 1000
8
Luis Vazquez

私は同じ問題を抱えていたので(SolarisではShell usleepを使用していません)、次のように自分で作成しました。

  #include "stdio.h"
  int main(int argc, char **argv) {
     if(argc == 2) { usleep(atoi(argv[1])); }
     return 0;
}

引数をチェックしません-保持したい場合は、適切に記述したものをお勧めしますが、それによって(gcc usleep.c -o usleep)、穴から抜け出すことができます。

5
jrichemont

私はusleepのアイデアが好きですが、その下でコメントを付けることはできません。これが私を助けてくれたので、私の提案がusleepのアイデアを改善できることを願っています。

https://github.com/Fedora-sysv/initscripts/blob/3c3fe4a4d1b2a1113ed302df3ac9866ded51b01b/src/usleep.c は、redhatエコシステム上のusleep.cの実際のソースコードです。

Solarisでコンパイルしてみてください。おそらく https://www.opencsw.org/packages/libpopt0/ が必要でしょう。

0
edzzz