シェル:「sleep」を使用せずにコマンドを遅延させることは可能ですか?


21

使用せずにコマンドを遅延させるための代替、代替、またはbashトリックはありますsleepか?たとえば、実際にスリープを使用せずに以下のコマンドを実行します。

$ sleep 10 && echo "This is a test"

42
何が問題なのsleepですか?
ムル

5
好奇心以外に本当の理由はありません。私は、いくつかの代替ソリューションを学ぶことは面白いと思いました。私が考えるat1かもしれませんが、私は、任意の使用例を見つけることができませんでした。
user321697

1
@ user321697“ at”は、単一のジョブをスケジュールすることです。これらはatdサービスによって実行されるため、シェルスクリプトを一時停止しません。atの使用例の1つは、スクリプトがwhileループで表示されるのをスクリプトが待機している間に、指定された時間(非同期)に何かを実行し、終了時にマーカーファイルを作成することです。スクリプトにSIGCONTを送信するジョブをスケジュールし、SIGSTOPを送信してスクリプトをフリーズすることにより、同様の効果を達成できます。
グレガブレメック

1
私はみんながスピンロックを提案することを期待してここに来ました。私はすべての答えに喜んで驚いています。
ダーン・ヴァン・ホーク

3
再:「好奇心」 -でunix.stackexchange.com/help/dont-askは、その要件に注意してください「あなたは唯一の実用的、釈明質問をする必要があり、あなたが直面している現実の問題に基づいて。 -これはよくなっていることガイドラインはそれをかなりまれな例外にしているという論争にもかかわらず受け取った。
チャールズダフィー

回答:


17

次の選択肢sleepatありcronます。sleepこれらに反して、実行に必要な時間を提供する必要があります。

  • atd実行して、サービスが実行されていることを確認しますservice atd status
    ここで、日付がUTCの午前11時17分であるとします。UTC 11:25にコマンドを実行する必要がある場合、構文は次のとおりですecho "This is a test" | at 11:25
    ここでatd、デフォルトではジョブの完了をログに記録しないことに注意してください。詳細については、このリンクを参照してください。アプリケーションが独自のロギングを持っている方が良いです。

  • あなたには、ジョブをスケジュールすることができcron、より参照してください、:man cronそのオプションが表示されたりcrontab -e、新しいジョブを追加します。/var/log/cronジョブの実行に関する情報を確認できます。

FYI sleep system call は現在の実行を中断し、渡された引数に基づいてスケジュールします。

編集:

@Gaiusが述べたように、コマンドに数分の時間を追加することもatできますが、時間はある12:30:30と言って、今ではスケジューラを実行しましたnow +1 minutes。60秒に変換される1分が指定されてatいても12:31:30、ジョブを実行するまで実際に待機するのではなく、でジョブを実行し12:31:00ます。時間単位はにすることができますminutes, hours, days, or weeks。詳細についてはman at

例えば: echo "ls" | at now +1 minutes


7
これは事実ではありません。1分で実行するために、たとえば+1分でatジョブをスケジュールできます
Gaius

29

ではbash組み込みコマンド、あなたが行うことができます。

coproc read -t 10 && wait "$!" || true

を使用せずに10秒間スリープするsleepcoprocそのことを確認することであるreadのSTDINは何が今までから出て来ないだろうパイプです。これは、オプションが設定されている場合、シェルが終了するSIGALRM配信がの終了ステータスに反映される|| trueためです。waiterrexit

他のシェルでは:

mkshそして、ksh93しているsleepビルトインノーポイント、そこに何か他のものを使用して(どちらもサポートしていてもread -t)。

zshもサポートしますがread -t、の周りselect()に組み込みのラッパーもあるため、以下も使用できます。

zmodload zsh/zselect
zselect -t 1000 # centiseconds

インタラクティブシェルセッションから実行するようにスケジュールする場合は、のzsh/schedモジュールzshも参照してください。


考えread -t 10 < /dev/zero || trueますか?
ジェフシャラー

5
@JeffSchallerそれは忙しいループなので、私はそれを避けるでしょう。
ステファンシャゼル

@StéphaneChazelas私はそれが忙しいループになるとは思わないだろう-私はreadselect(2)または類似のものを使用してシェルが実装されると期待するだろう(このタイムアウトに対する読み取りが良い答えであることを意味する)。私はあなたに矛盾するのではなく、驚きを表明していますが、これについてのさらなる議論を指摘できますか?
ノーマングレイ

5
@NormanGray /dev/zeroは、無限量のデータ(NULバイト)を含むファイルです。そのreadため、これらの10秒間にできる限り多くのデータを読み取ります。ありがたいことに、bash変数にNULバイトを格納することをサポートしていない場合、メモリを消費しませんが、それでもCPUリソースを消費します。
ステファンシャゼラス

1
@NormanGrayは、端末から実行/dev/stdoutする場合はttyデバイスになるため、副作用(バックグラウンドで実行する場合はスクリプトを停止するなど)が発生し、ユーザーがEnterキーを押すと復帰します。read -t 10 /dev/stdout | :Linuxで動作しますが、Linuxでのみcoproc動作しますが、OSに関係なく動作します。
ステファンシャゼラス

7

他のいくつかのアイデア。

top -d10 -n2 >/dev/null

vmstat 10 2 >/dev/null

sar 10 1 >/dev/null

timeout 10s tail -f /dev/null

1
あなたは私のタイムリミット/タイムアウトのアイデアを「盗みました」... +1
ルイFリベイロ

1
ああ、ありがとう、私は眠れない状況にありました、トップは素晴らしいです!
ファイヤードラゴンDoL

6

の非標準-t delayオプションを使用することを提案している答えがあるのでread、標準シェルでタイムアウトした読み取りを行う方法を次に示します。

{ ss=`stty -g`; stty -icanon min 0 time 20; read foo; stty "$ss"; }

の引数stty timeは10分の1秒です。


5

bash組み込み変数$SECONDSとビジーループの使用:

for((target=$((SECONDS + 10)); SECONDS < target; true)); do :; done

2
それにもかかわらず9〜10秒でどこまでの期間中の効果ポーズの場合と(が原因のバグをbashzshmksh同様の問題があったが、以降に修正されました)
ステファンChazelas

7
熱を作る良い方法。
ctrl-alt-delor

6
熱気に満ちていると非難されるのは初めてではありません!:)
ジェフシャラー

4

本の中で最も古いトリック:

read && echo "This is a test"

打つだけでEnter続行します!


プロセスをインタラクションなしで実行する必要がある場合、またはバックグラウンドで実行する必要がある場合、これは適切ですか?
ss_iwe

正解:しかし、それは元の質問によるOPの要件の1つではなかったため、依然として有効な答えです...
;

1
OPは具体的に(withを使用sleep)の例を示し、なしで同等の代替を要求します。だから、read申し訳ありませんが、解析しません。;)
AnoE

@AnoEStéphaneの答えはもちろん最高です。私のものが一番古いです--- press «enter» to continue --- ;-)
Fabby

4

BASICを実行しているマイクロコンピューターの時代には、通常、遅延は空のループで達成されていました。

FOR I = 1 TO 10000:NEXT

同じ原則を使用して、シェルスクリプトに遅延を挿入できます。

COUNTER=0; while [ $COUNTER -lt 10000 ]; do :; let COUNTER=COUNTER+1; done

もちろん、このアプローチの問題は、プロセッサの速度に応じて(または同じマシンでも負荷が異なる場合でも)遅延の長さがマシンごとに異なることです。とは異なりsleep、おそらくCPU(またはそのコアの1つ)を最大化します。


2
熱を作る良い方法。
ctrl-alt-delor

2
遅延ループは、UnixライクなOSを実行できる最新のCPUでの非常に短いスリープ(デバイスドライバーでの数ナノ秒またはクロックサイクル)を除く、あらゆるものに対するひどいアイデアです。つまり、他のプロセスをスケジュールしたり、タイマー割り込みで起動する前に低電力スリープ状態に入るなど、CPUが待機中に他のことを実行できないほど短いスリープ。動的なCPU周波数により、1秒あたりのカウントの遅延ループを調整することさえ不可能になります。ただし、最小クロック遅延は、ランプアップする前に低クロック速度で長時間スリープする可能性があります。
ピーター

古代のコンピューターの電力消費は、ワークロードへの依存度がはるかに低かった。最新のCPUは、チップの異なる部分を可能な限り動的にパワーダウンして溶けないようにする必要があります(たとえば、整数コードのみが実行されている間にFPUまたはSIMD実行ユニットの一部をパワーダウンするか、少なくともチップの一部にクロック信号をゲートします)切り替える必要はありません)。また、アイドル時に低消費電力のスリープ状態に入る(タイマー割り込みを待つ無限ループでスピンするのではなく)ことは、あなたが言及した古代のコンピューターよりも最近のものです。
ピーター

CPU履歴の詳細については、「最新のマイクロプロセッサA 90分ガイド」を参照してください!- lighterra.com/papers/modernmicroprocessors
ピーター

3

ビルトインはありません。ビルトインと同じですsleepsleepビルトインでない限り)。ただし、待機する他のコマンドがいくつかあります。

いくつかが含まれます。

  • atおよびcron:特定の時間にタスクをスケジュールするために使用されます。

  • inotifywait:ファイル、またはファイルの変更/削除/追加などを待つために使用されます


これをありがとう。スケジュールされたタスク(今から10秒後)を実行するための例を提供できますatか?
user321697

1
編集と賛成票! ;-)
Fabby

cronにタスクを保存しcrontabますか?atスケジュールされたデータはどこに保存されますか?
user321697

@ user321697すでにここで
ファビー

編集内容をQに戻してすみません。すべての最も単純な答えを無効にするOP質問の主な目的を変更しました... ¯\ _(ツ)_ /
¯– Fabby

3

Land of Windows and Batchesのクラシック:

ping -c 11 localhost >/dev/null && echo "This is a test"

ファイアウォールまたはネームシステムの設定ミスにより、大幅な遅延が追加される可能性があります。
スペクトル

1
127.0.0.1 ... @spectras
AnoE

1
ありがたいことに、Windowsはネイティブでスリープをサポートするようになったため、必要ありません。
Baldrickk

1
@AnoE>は、ファイアウォール部分ではなく、ネームシステム部分を解決します。一般的ではありませんが、ローカルインターフェイスでpingをサイレントドロップするように構成できます。これにより、pingの待機時間が長くなります。
スペクトル

「好きな」思い出のために+1
AC

0

ファイル内の新しい行を対話的に待機する場合は、

tail -f

ファイルシステムの変更を待っていますか?次に使用します

inotify / inoticoming

また、「待機」の意味に応じて、他のオプションがあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.