ইউনিক্স কমান্ডটি প্রতি x সেকেন্ডে চিরতরে পুনরাবৃত্তি করুন


480

একটি অন্তর্নির্মিত ইউনিক্স কমান্ড রয়েছে repeatযার প্রথম আর্গুমেন্টটি কোনও কমান্ডের পুনরাবৃত্তি করার সংখ্যা, যেখানে কমান্ডটি (কোনও আর্গুমেন্ট সহ) অবশিষ্ট আর্গুমেন্ট দ্বারা নির্দিষ্ট করা হয় repeat

উদাহরণ স্বরূপ,

% repeat 100 echo "I will not automate this punishment."

প্রদত্ত স্ট্রিংটি 100 বার প্রতিধ্বনিত হবে এবং তারপরে বন্ধ হবে।

আমি একটি অনুরূপ কমান্ড চাই - আসুন এটি কল করুন forever- এটি প্রথম যুক্তি ব্যতীত একইভাবে কাজ করে যা পুনরাবৃত্তিগুলির মধ্যে বিরতি দেওয়ার জন্য সেকেন্ডের সংখ্যা এবং এটি চিরতরে পুনরাবৃত্তি হয়। উদাহরণ স্বরূপ,

% forever 5 echo "This will get echoed every 5 seconds forever and ever."

আমি ভেবেছিলাম আমি লেখার আগে এই জাতীয় জিনিস উপস্থিত থাকলে জিজ্ঞাসা করব। আমি জানি এটি 2-লাইনের পার্ল বা পাইথন স্ক্রিপ্টের মতো তবে সম্ভবত এটি করার আরও একটি স্ট্যান্ডার্ড উপায় আছে। যদি তা না হয় তবে আপনার পছন্দের স্ক্রিপ্টিং ভাষা, রোসেটা স্টোন স্টাইলে কোনও সমাধান পোস্ট করুন নির্দ্বিধায় ।

পিএস: সম্ভবত এটি করার একটি আরও ভাল উপায় হ'ল repeatপুনরাবৃত্তি করার সময়গুলির সংখ্যা (-1 অর্থ অনন্ত সহ) এবং পুনরাবৃত্তির মধ্যে ঘুমানোর জন্য সেকেন্ডের সংখ্যা উভয়ই গ্রহণ করা general উপরের উদাহরণগুলি তখন হয়ে যাবে:

% repeat 100 0 echo "I will not automate this punishment."
% repeat -1 5 echo "This will get echoed every 5 seconds forever."

1
কেন নয়: পুনরায় [-tt সময়] [-n সংখ্যা] কমান্ড [আরগস ...]?
জোনাথন লেফলার

17
কুল। দুর্ভাগ্যক্রমে আমার উবুন্টু এবং আমার এআইএক্স পুনরাবৃত্তি হ'ল আদেশটি পাওয়া যায় নি । আপনি একটি করতে পারেন type repeatএবং আমাকে জানতে পারেন কোথা থেকে আসছে?

3
আমি উবুন্টুতেও আছি এবং পুনরায় ইনস্টল করা নেই। এটি কীভাবে ইনস্টল করা যায় সে সম্পর্কে কোনও তথ্য সহায়ক হবে।
ররি

7
repeatcsh এবং tcsh এ বিল্টিন কমান্ড।
কিথ থম্পসন

2
@KeithThompson, csh শেল, tcsh শেল এবং zsh । যদিও এটি একটি বিল্টিনের চেয়ে বেশি কীওয়ার্ড
স্টাফেন চেজেলাস

উত্তর:


615

watchকমান্ড চেষ্টা করুন ।

Usage: watch [-dhntv] [--differences[=cumulative]] [--help] [--interval=<n>] 
             [--no-title] [--version] <command>`

যাতে:

watch -n1  command

কমান্ডটি প্রতি সেকেন্ডে চালিত হবে (ভাল, প্রযুক্তিগতভাবে, প্রতি এক সেকেন্ড প্লাস commandহিসাবে চালাতে যে সময় লাগে watch(কমপক্ষে procpsএবং busyboxবাস্তবায়নগুলি কেবল দুই রানের মধ্যে এক সেকেন্ড ঘুমায় command), চিরকাল।

আপনি কি execপরিবর্তে কমান্ডটি পাস করতে চান sh -c, -xবিকল্পটি ব্যবহার করুন :

watch -n1 -x command

ম্যাকোজে আপনি ম্যাক পোর্টগুলিwatch থেকে পেতে পারেন :

port install watch

অথবা আপনি হোমব্রু থেকে এটি পেতে পারেন :

brew install watch

2
আপনি এটি ইনস্টল করতে ম্যাকপোর্টস ব্যবহার করতে পারেন। sudo পোর্ট ইনস্টল ওয়াচ

10
হোমব্রিউতেও পাওয়া যায় (ব্রিউ ইনস্টল ওয়াচ)।
লাইল 21

28
একটি নতুন শক্তিশালী সরঞ্জামের জন্য +1। আমি অভ্যস্ত while true; do X; sleep Y; done- এটি উপায় ভাল।
আদম মতান

4
এই সরঞ্জামটির সাথে (কমপক্ষে উবুন্টুতে) সমস্যা হ'ল এটি পূর্ণস্ক্রিনটিকে বাধ্য করে, সুতরাং যদি আমি কিছু পর্যায়ক্রমিক তথ্য ডাম্প করি তবে আমি পূর্ববর্তী তথ্যটি হারাব।
scorpiodawg

4
এটি cmdwatchফ্রিবিএসডি-তে বলা হয় (বন্দরগুলি থেকে sysutils/cmdwatch)।
ওউকি

243

সজোরে আঘাত

while+ sleep:

while true
do 
    echo "Hi"
    sleep 1
done

শর্টহ্যান্ড ওয়ান-লাইনারের মতো একই জিনিস এখানে (নীচের মন্তব্যগুলি থেকে):

while sleep 1; do echo "Hi"; done

ব্যবহার ;পৃথক কমান্ড এবং ব্যবহার sleep 1জন্য whileযেহেতু এটি সবসময় সত্য ফেরৎ পরীক্ষা। আপনি লুপে আরও কমান্ড রাখতে পারেন - কেবল তাদের দিয়ে আলাদা করুন;


2
আমি বিশ্বাস করি এটি জেনেরিক বোর্ন শেল-তেও লিখিতভাবে কাজ করে।
dmckee

5
@ ড্রিভস, "ব্যবহার করে"; বিভাজক হিসাবে, আদেশগুলি একটি লাইনে ছাড় দেওয়া যায় can টুনির উত্তরটি উদাহরণ হিসাবে দেখুন
bbaja42

56
স্লিপ 1 সর্বদা সত্য ফিরে আসে তাই আপনি এটিকে সময়কাল হিসাবে ব্যবহার করতে পারেন। বিশ্বের সর্বাধিক পঠনযোগ্য জিনিস নয় তবে একেবারে বৈধতা: ঘুমের সময় 1; "হাই" প্রতিধ্বনি করুন; সম্পন্ন
ডেভিড কোস্টা

3
@ ডেভিড কোস্টা: আপনি একটি যুক্তিসঙ্গত বক্তব্য রেখেছিলেন, তবে সবসময় সত্য sleepহয় না । Such এই জাতীয় লুপগুলি ব্যবহার করা হয়েছে (দীর্ঘতর বিলম্বের সাথে হলেও) কারণ ঘুম প্রক্রিয়াটি হত্যার সাথে এটিকে নিখুঁতভাবে শেষ করার উপায় রয়েছে।
ইনকনিস মিসেসি

2
@ ইন্নিসনস মিরসি আমি এটির কথা ভাবি নি, এটি আসলে শূন্যটি কেবল তখনই ফিরে আসে যখন সময়টি শেষ হয় এবং যখন এটি সংকেত দ্বারা সমাপ্ত হয় তখন শূন্য হয় না। এটি দেখানোর জন্য ধন্যবাদ
ডেভিড কোস্টা

71

এটি অন্যান্য while+sleepউত্তরের একটি সংক্ষিপ্ত সংস্করণ , যদি আপনি আপনার প্রতিদিনের রুটিন হিসাবে এই ধরণের কাজগুলি প্রায়শই চালাচ্ছেন তবে এটি আপনাকে অপ্রয়োজনীয় কী প্রেসগুলি থেকে বাঁচায় এবং যদি আপনার কমান্ড লাইনটি আরও বুঝতে শুরু করে তবে এটি কিছুটা সহজ। তবে এই প্রথম ঘুম দিয়ে শুরু হয়।

আপনার যদি কোনও কিছু অনুসরণ করতে মেশিন লোডের মতো এক-লাইন আউটপুট থাকে তবে এটি সাধারণত কার্যকর হয়:

while sleep 1; do uptime; done

হ্যাঁ. এটি ইউইউসির পাশেই নথিভুক্ত করা উচিত।
জোহান

10
এবং আপনি যদি এটি "ঘড়ি" এর মতো পরিচালনা করতে চান তবে আপনি করতে পারেনwhile clear; do date; command;sleep 5; done
জোহান

বাহ, while sleepসংমিশ্রণের জন্য ধন্যবাদ , কীস্টোক সংরক্ষণ করে!
জর্জ ওয়াই

45

এখন পর্যন্ত পোস্ট করা সমস্ত উত্তরগুলির মধ্যে একটি সমস্যা হ'ল কমান্ড কার্যকর হওয়ার সময়টি প্রস্থান করতে পারে। উদাহরণস্বরূপ, আপনি যদি sleep 10কমান্ডগুলির মধ্যে একটি করেন এবং কমান্ডটি চালাতে 2 সেকেন্ড সময় নেয়, তবে এটি প্রতি 12 সেকেন্ডে চলতে চলেছে; এটি চলতে যদি একটি পরিবর্তনশীল পরিমাণ সময় নেয় তবে দীর্ঘমেয়াদে এটি চালিত সময়টি অনাকাঙ্ক্ষিত হতে পারে।

এটি আপনি যা চান ঠিক তেমন হতে পারে; যদি তাই হয় তবে অন্য সমাধানগুলির মধ্যে একটি ব্যবহার করুন বা এটি ব্যবহার করুন তবে sleepকলটি সহজ করুন ।

এক মিনিটের রেজোলিউশনের জন্য, প্রতিটি কমান্ড যতক্ষণ সময় নেয় তা নির্বিশেষে ক্রোন জবস নির্দিষ্ট সময়ে চলবে। (আসলে আগেরটি এখনও চলমান থাকলেও নতুন ক্রোন জব চালু হবে))

এখানে একটি সহজ পার্ল স্ক্রিপ্ট যা পরবর্তী অন্তর পর্যন্ত ঘুমায়, সুতরাং উদাহরণস্বরূপ 10 সেকেন্ডের ব্যবধান সহ কমান্ডটি 12:34:00, 12:34:10, 12:34:20, ইত্যাদি চলতে পারে, এমনকি যদি কমান্ড নিজেই কয়েক সেকেন্ড সময় নেয়। কমান্ডটি intervalসেকেন্ডের বেশি চললে, পরবর্তী অন্তরটি এড়িয়ে যাবে (ক্রোনের বিপরীতে)। ব্যবধানটি যুগের তুলনায় গণনা করা হয়, সুতরাং 86400 সেকেন্ড (1 দিন) এর বিরতি মধ্যরাত ইউটিসি-তে চলবে।

#!/usr/bin/perl

use strict;
use warnings;

if (scalar @ARGV < 2) {
    die "Usage: $0 seconds command [args...]\n";
}

$| = 1;  # Ensure output appears

my($interval, @command) = @ARGV;

# print ">>> interval=$interval command=(@command)\n";

while (1) {
    print "sleep ", $interval - time % $interval, "\n";
    sleep $interval - time % $interval;
    system @command; # TODO: Handle errors (how?)
}


1
ড্রাফট কমাতে ব্যাশ সহজ (যদিও এটি স্লিপ কমান্ডের কারণে খুব দীর্ঘ ব্যবহারের উইন্ডোগুলির উপর দিয়ে প্রবাহিত হতে পারে এবং ব্যাশ নিজেই তার ক্ষুদ্র প্রয়োগের সময়গুলি সংগ্রহ করে): while :; do sleep 1m & command; wait; done
গণিত

1
@ ম্যাথ: চালাক আপনার যদি বর্তমান শেলটিতে অন্যান্য পটভূমি প্রক্রিয়াগুলি চলমান থাকে তবে এটি কাজ করে না ( waitতাদের সকলের জন্য অপেক্ষা করবে)। প্রক্রিয়াটির পিআইডি কোথায়, তা পরিবর্তন waitকরে এটি স্থিরযোগ্য । একটি উত্তর হিসাবে পোস্ট করুন এবং আমি এটি upvote করব। তবে এটি একটি ইন্টারেক্টিভ শেলের মধ্যে কিছু বহিরাগত আউটপুট উত্পাদন করে। wait $!$!sleep
কিথ থম্পসন

29

আমি মনে করি এখানে এখন পর্যন্ত সমস্ত উত্তর হয় খুব জটিল হয়, বা পরিবর্তে একটি অন্য প্রশ্নের উত্তর:

  • "কীভাবে বারবার একটি প্রোগ্রাম চালানো যায় যাতে প্রোগ্রাম শেষ হওয়ার পরে এক্স সেকেন্ডের বিলম্ব হয় এবং পরবর্তীটি শুরু হয়"

আসল প্রশ্নটি ছিল:

  • "প্রতি X সেকেন্ডে একটি প্রোগ্রাম কীভাবে চালানো যায়"

কমান্ডটি শেষ করতে সময় লাগে যখন এই দুটি খুব আলাদা জিনিস।

উদাহরণস্বরূপ স্ক্রিপ্টটি ধরুন foo.sh(ভান করুন এটি এমন একটি প্রোগ্রাম যা সম্পূর্ণ হতে কয়েক সেকেন্ড সময় নেয়)।

#!/bin/bash
# foo.sh
echo `date +"%H:%M:%S"` >> output.txt;
sleep 2.5;
# ---

আপনি প্রতি সেকেন্ডে এটি চালনা করতে ইচ্ছুক, এবং বেশিরভাগই পরামর্শ দেবে watch -n1 ./foo.sh, বা while sleep 1; do ./foo.sh; done। তবে এটি আউটপুট দেয়:

15:21:20
15:21:23
15:21:27
15:21:30
15:21:34

যা প্রতি সেকেন্ডে হুবহু চালানো হচ্ছে না। এমনকি -pপতাকা সহ, man watchপৃষ্ঠাটি যেমন এটি সমাধান করতে পারে বলে প্রস্তাব দেয়, ফল একই।

পছন্দসই কাজটি সম্পাদনের একটি সহজ উপায়, যা কিছু লোক স্পর্শ করে, তা হ'ল ব্যাকগ্রাউন্ডে কমান্ডটি চালানো। অন্য কথায়:

while sleep 1; do (./foo.sh &) ; done

এবং এটি সব আছে।

আপনি এটি প্রতি 500 এমএস দিয়ে চালাতে পারেন sleep 0.5, বা আপনার যা আছে।


1
যারা বিভিন্ন উত্তরে ভোট দিয়েছেন, তারা আপনার উত্তরের কমনীয়তা বুঝতে পারে না ...
সার্জ স্ট্রোব্যান্ড

আপনার প্রোগ্রামের পার্শ্ব প্রতিক্রিয়া না থাকলে এটি ভাল। প্রোগ্রামটি যদি ব্যবধানের চেয়ে বেশি সময় নেয় তবে পার্শ্ব প্রতিক্রিয়া হস্তক্ষেপ করতে পারে (কোনও ফাইলকে ওভাররাইট করার মতো)। যদি প্রোগ্রামটি অন্য কোনও কিছুর জন্য অপেক্ষা করে, এবং সেই অন্য কিছু চিরদিনের জন্য নিচ্ছে, তবে আপনি অনির্দিষ্টকালের জন্য আরও এবং বেশি পটভূমি কাজ শুরু করছেন। সতর্কতার সাথে ব্যবহার করুন.
জন Moeller

4
একসাথে একাধিক ./foo.sh চালানো হয় না, তবে প্রতি সেকেন্ডে 1 এর চেয়ে দ্রুত নয়: while :; do sleep 1 & ./foo.sh; wait; done
গণিত

হ্যাঁ, এটি প্রবাহিত হবে, প্রতিটি লুপে কয়েক মিলিসেকেন্ড, তবে এটি হবে। date +"%H:%M:%S.%N"Foo.sh তৈরি করুন প্রতিটি লুপের উপর কীভাবে ভগ্নাংশটি আস্তে আস্তে বাড়বে তা দেখতে।
ইসহাক

হ্যাঁ, এটি সত্য যে বেশিরভাগ উত্তর আক্ষরিক অর্থে প্রশ্নটিকে সম্বোধন করে না । তবে এটি প্রায় নিরাপদ বাজি যা তারা ওপি কী চায় তা উত্তর দেয়। এটি যদি ওপি প্রকৃতপক্ষে কোনও উত্তর গ্রহণ করে থাকে তবে এটি একটি নিরাপদ বাজি হতে পারে ... তবে এটি ভাল, যদি আপনি সম্ভাব্য পার্শ্ব প্রতিক্রিয়া সম্পর্কে অবগত হন এবং আপনি নিশ্চিত হন যে কমান্ডের গড় রান সময়টি চক্রের সময়কে অতিক্রম করবে না
অস্পেক্স

17

ইন bash:

bash -c 'while [ 0 ]; do echo "I will not automate this punishment in absurdum."; done'

( echoকোনও আদেশ দ্বারা প্রতিস্থাপন করা যেতে পারে ...

বা এতে perl:

perl -e 'for (;1;) {print "I will not automate this punishment in absurdum.\n"}'

যেখানে print "I will not automate this punishment in absurdum.\n"ব্যাকটিক্স (`) দিয়ে ঘিরে থাকা" যে কোনও "কমান্ডের সাহায্যে প্রতিস্থাপন করা যেতে পারে।

এবং একটি বিরতি sleepজন্য, লুপ ভিতরে একটি বিবৃতি যোগ করুন :

bash -c 'while [ 0 ]; do echo "I will not automate this punishment in absurdum."; sleep 1; done'

এবং

perl -e 'for (;1;) {print "I will not automate this punishment in absurdum.\n"; sleep 1}'

16
while [ 0 ]এটি লিখার একটি খারাপ উপায়। এর অর্থ 0দৈর্ঘ্য> 0 সহ একটি স্ট্রিং while [ 1 ]বা while [ jeff ]একই জিনিসটি করবে। লেখাই ভাল while true
মিকেল

5
@ মাইকেল: বাwhile :
কিথ থমসন

10

সাম্প্রতিক ব্যাশ> = 4.2 সাম্প্রতিক লিনাক্স কার্নেলের আওতায়, ভিত্তিক উত্তর।

মৃত্যুদণ্ড কার্যকর করার সময় সীমাবদ্ধ করার জন্য, কাঁটাচামচ নেই ! শুধুমাত্র বিল্ট-ইন ব্যবহার করা হয়।

এর জন্য, আমি readপরিবর্তে বিল্টিন ফাংশন ব্যবহার করি sleep। দুর্ভাগ্যক্রমে এটি নটি সেশনগুলির সাথে কাজ করবে না ।

অনুরোধ হিসাবে দ্রুত ফাংশন " repeat":

repeat () {
   local repeat_times=$1 repeat_delay=$2 repeat_foo repeat_sleep
   read -t .0001 repeat_foo
   if [ $? = 1 ] ;then
       repeat_sleep() { sleep $1 ;}
   else
       repeat_sleep() { read -t $1 repeat_foo; }
   fi
   shift 2
   while ((repeat_times)); do
        ((repeat_times=repeat_times>0?repeat_times-1:repeat_times))
        "${@}"
        ((repeat_times))&& ((10#${repeat_delay//.})) &&
            repeat_sleep $repeat_delay
   done
}

উদ্ধৃত স্ট্রিংগুলির সাথে সামান্য পরীক্ষা:

repeat 3 0 printf "Now: %(%T)T, Hello %s.\n" -1 Guy
Now: 15:13:43, Hello Guy.
Now: 15:13:43, Hello Guy.
Now: 15:13:43, Hello Guy.

repeat -1 .5 printf "Now: %(%T)T, Hello %s.\n" -1 Guy
Now: 15:14:14, Hello Guy.
Now: 15:14:14, Hello Guy.
Now: 15:14:15, Hello Guy.
Now: 15:14:15, Hello Guy.
Now: 15:14:16, Hello Guy.
Now: 15:14:16, Hello Guy.
Now: 15:14:17, Hello Guy.
Now: 15:14:17, Hello Guy.
Now: 15:14:18, Hello Guy.
Now: 15:14:18, Hello Guy.
^C

জমা দেওয়া কমান্ডের গ্রানুলারিটি এবং সময়কালের উপর নির্ভর করে ...

সাম্প্রতিক লিনাক্স কার্নেলের আওতায় /proc/timer_listন্যানোসেকেন্ডে সময় সম্পর্কিত তথ্য রয়েছে এমন একটি প্রোফিল রয়েছে।

আপনি যদি কমান্ড একবারে চালাতে চান তবে আপনার কমান্ডটি এক সেকেন্ডেরও কম সময়ে শেষ হতে হবে! আর সেখান থেকে আপনি করতে হবে sleepশুধুমাত্র বাকি বর্তমান সেকেন্ডের।

যদি বিলম্ব আরও গুরুত্বপূর্ণ হয় এবং আপনার আদেশের জন্য উল্লেখযোগ্য সময় প্রয়োজন হয় না, আপনি এটি করতে পারেন:

command=(echo 'Hello world.')
delay=10
while :;do
    printf -v now "%(%s)T" -1
    read -t $(( delay-(now%delay) )) foo
    ${command[@]}
  done.

তবে যদি আপনার লক্ষ্যটি সূক্ষ্ম গ্রানুলারিটি অর্জন করা হয় তবে আপনাকে এগুলি করতে হবে:

সেকেন্ড শুরু না হওয়া পর্যন্ত অপেক্ষা করতে ন্যানোসেকেন্ডের তথ্য ব্যবহার করুন ...

এই জন্য, আমি একটি সামান্য বাশ ফাংশন লিখেছি:

# bash source file for nano wait-until-next-second

mapfile  </proc/timer_list _timer_list
for ((_i=0;_i<${#_timer_list[@]};_i++));do
    ((_c+=${#_timer_list[_i]}))
    [[ ${_timer_list[_i]} =~ ^now ]] && TIMER_LIST_READ=$_c
    [[ ${_timer_list[_i]} =~ offset:.*[1-9] ]] && \
        TIMER_LIST_OFFSET=${_timer_list[_i]//[a-z.: ]} && \
        break
done
unset _i _timer_list _c
readonly TIMER_LIST_OFFSET TIMER_LIST_READ
waitNextSecondHires() {
    local nsnow nsslp
    read -N$TIMER_LIST_READ nsnow </proc/timer_list
    nsnow=${nsnow%% nsecs*}
    nsnow=$((${nsnow##* }+TIMER_LIST_OFFSET))
    nsslp=$((2000000000-10#${nsnow:${#nsnow}-9}))
    read -t .${nsslp:1} foo
}

তাদের উত্সাহ দেওয়ার পরে, আপনি করতে পারেন:

command=(echo 'Hello world.')
while :;do
    waitNextSecondHires
    ${command[@]}
  done.

${command[@]}তুলনায় তুলনায় সরাসরি কমান্ড লাইনে চালান

command=(eval "echo 'Hello world.';sleep .3")
while :;do
    waitNextSecondHires
    ${command[@]}
  done.

এই অবশ্যই একই ফলাফল দিতে হবে।

অনুরোধ অনুসারে হায়ার ফাংশন " repeat":

আপনি এটি উত্স হতে পারে:

mapfile  </proc/timer_list _timer_list
for ((_i=0;_i<${#_timer_list[@]};_i++));do
    ((_c+=${#_timer_list[_i]}))
    [[ ${_timer_list[_i]} =~ ^now ]] && TIMER_LIST_READ=$_c
    [[ ${_timer_list[_i]} =~ offset:.*[1-9] ]] && \
        TIMER_LIST_OFFSET=${_timer_list[_i]//[a-z.: ]} && \
        break
done
unset _i _timer_list _c
readonly TIMER_LIST_OFFSET TIMER_LIST_READ

repeat_hires () {
    local repeat_times=$1 repeat_delay=$2 repeat_foo repeat_sleep repeat_count
    read -t .0001 repeat_foo
    if [ $? = 1 ] ;then
        repeat_sleep() { sleep $1 ;}
    else
        repeat_sleep() { read -t $1 repeat_foo; }
    fi
    shift 2
    printf -v repeat_delay "%.9f" $repeat_delay
    repeat_delay=${repeat_delay//.}
    read -N$TIMER_LIST_READ nsnow </proc/timer_list
    nsnow=${nsnow%% nsec*}
    started=${nsnow##* }
    while ((repeat_times)); do
        ((repeat_times=repeat_times>0?repeat_times-1:repeat_times))
        "${@}"
        ((repeat_times)) && ((10#$repeat_delay)) && {
            read -N$TIMER_LIST_READ nsnow </proc/timer_list
            nsnow=${nsnow%% nsec*}
            nsnow=${nsnow##* }
            (( (nsnow - started) / 10#$repeat_delay - repeat_count++ )) &&
                printf >&2 "WARNING: Command '%s' too long for %f delay.\n" \
                           "${*}" ${repeat_delay:0:${#repeat_delay}-9
                           }.${repeat_delay:${#repeat_delay}-9}
            printf -v sleep "%010d" $((
                10#$repeat_delay - ( ( nsnow - started ) % 10#$repeat_delay ) ))
            repeat_sleep ${sleep:0:${#sleep}-9}.${sleep:${#sleep}-9}
        }
    done
}

তারপরে চেষ্টা করুন:

time repeat_hires 21 .05 sh -c 'date +%s.%N;sleep .01'
1480867565.152022457
1480867565.201249108
1480867565.251333284
1480867565.301224905
1480867565.351236725
1480867565.400930482
1480867565.451207075
1480867565.501212329
1480867565.550927738
1480867565.601199721
1480867565.651500618
1480867565.700889792
1480867565.750963074
1480867565.800987954
1480867565.853671458
1480867565.901232296
1480867565.951171898
1480867566.000917199
1480867566.050942638
1480867566.101171249
1480867566.150913407

real    0m1.013s
user    0m0.000s
sys     0m0.016s

time repeat_hires 3 .05 sh -c 'date +%s.%N;sleep .05'
1480867635.380561067
WARNING: Command 'sh -c date +%s.%N;sleep .05' too long for 0.050000 delay.
1480867635.486503367
WARNING: Command 'sh -c date +%s.%N;sleep .05' too long for 0.050000 delay.
1480867635.582332617

real    0m0.257s
user    0m0.000s
sys     0m0.004s

read -tএটি একটি অন্তর্নির্মিত , যখন sleepনেই। এটি সীমান্তে প্রভাব ফেলতে পারে (অর্থাত্ [কী: প্রত্যাবর্তন] নিঃশব্দে ঘুমকে বাধা দেয় ), তবে এটি পরীক্ষার মাধ্যমে চিকিত্সা করা যেতে পারে$foo
এফ হৌরি

খুব চিত্তাকর্ষক উত্তর
gena2x

4

এটি চেষ্টা করে দেখতে (বাশ)?

forever ()   {
    TIMES=shift;
    SLEEP=shift;
    if [ "$TIMES" = "-1" ]; then  
        while true;
        do 
            $@
            sleep $SLEEP
        done
    else
        repeat "$TIMES" $@ 
    fi; }

আমি শেল গরম করতে না, তাই উন্নতি স্বাগত জানায়। এবং আমার ডিস্ট্রোতে আমার "পুনরাবৃত্তি" কমান্ড আছে বলে মনে হয় না।

2
repeatcsh এবং tcsh এর জন্য নির্দিষ্ট।
কিথ থম্পসন

2
@ কিথথম্পসন: এবং জেডএস
থোর

4

পার্ল

#!/usr/bin/env perl
# First argument is number of seconds to sleep between repeats, remaining
# arguments give the command to repeat forever.

$sleep = shift;
$cmd = join(' ', @ARGV);

while(1) {
  system($cmd);
  sleep($sleep); 
}

4

বাশ এবং এর কয়েকটি স্বজাতীয় শাঁসের সুবিধাজনক (( ... ))স্বরলিপি রয়েছে যেখানে পাটিগণিতের অভিব্যক্তিগুলি মূল্যায়ন করা যেতে পারে।

সুতরাং আপনার তৃতীয় চ্যালেঞ্জের উত্তর হিসাবে, যেখানে প্রতিটি পুনরাবৃত্তির মধ্যে পুনরাবৃত্তি গণনা এবং বিলম্ব উভয়ই কনফিগারযোগ্য হওয়া উচিত, এটি করার একটি উপায় এখানে:

repeat=10
delay=1

i=0
while (( i++ < repeat )); do
  echo Repetition $i
  sleep $delay
done

এই উত্তরটি কীথের উত্তরে coveredাকা সময়সীমার সাথেও ভুগছে ।


এটি সেরা ছিল।
আহমদ আওইস

3

Gbrandt দ্বারা উল্লিখিত হিসাবে, watchকমান্ড উপলব্ধ থাকলে, অবশ্যই এটি ব্যবহার করুন। কিছু ইউনিক্স সিস্টেম, তবে এটি ডিফল্টরূপে ইনস্টল করা নেই (কমপক্ষে তারা যেখানে আমি কাজ করি সেখানে নেই)।

কিছুটা আলাদা সিনট্যাক্স এবং আউটপুট (BASH এবং SH এ কাজ করে) এর সাথে এখানে আরও একটি সমাধান রয়েছে:

while [ 1 ] ; do
    <cmd>
    sleep <x>
    echo ">>>>>>>>>>>>>" `date` ">>>>>>>>>>>>>>"
done

সম্পাদনা: আমি কিছু "অপসারণ করেছি।" সর্বশেষ প্রতিধ্বনি বিবৃতিতে ... আমার পার্ল দিনগুলি ধরে রাখা;)


3
while [ 1 ]শুধুমাত্র কাজ করে কারণ 1 টি স্ট্রিং হিসাবে ধরা হয়, ঠিক তেমন while [ -n 1 ]while [ 0 ]বা while [ jeff ]একই জিনিস করতে হবে। while trueআরও অনেক কিছু বোঝায়।
মাইকেল

3

যদি আপনার উদ্দেশ্যটি আপনার স্ক্রিনে কোনও বার্তা প্রদর্শন না করে এবং আপনি যদি মিনিটের নিরিখে কাজের পুনরাবৃত্তি করতে সক্ষম হন তবে ক্রোনট্যাব সম্ভবত আপনার সেরা হাতিয়ার হবে। উদাহরণস্বরূপ, আপনি যদি প্রতি মিনিটে আপনার আদেশটি কার্যকর করতে চান, আপনি নিজের crontabফাইলে এই জাতীয় কিছু লিখবেন :

* * * * * my_precious_command

দয়া করে আরও উদাহরণের জন্য টিউটোরিয়ালটি দেখুন। এছাড়াও, আপনি ক্রন্টব কোড জেনারেটর ব্যবহার করে খুব সহজেই সময় নির্ধারণ করতে পারেন ।


3

আমাদের দুজনেই থাকলে কী হত?

এখানে ধারণাটি রয়েছে: কেবল "বিরতি" দিয়ে, এটি চিরতরে পুনরাবৃত্তি করে। "বিরতি" এবং "বার" এর সাহায্যে, এটি "ইন্টারভাল" দ্বারা পৃথক হয়ে এই সংখ্যার পুনরাবৃত্তি করে।

ব্যবহার:

$ loop [interval [times]] command

সুতরাং, অ্যালগরিদমটি হ'ল:

  • তালিকাবদ্ধ
  • যদি $ 1 এ কেবলমাত্র সংখ্যা থাকে তবে এটি অন্তর (ডিফল্ট 2)
  • যদি $ 2 এ কেবলমাত্র সংখ্যা থাকে তবে এটি বারের সংখ্যা (ডিফল্ট অসীম)
  • এই পরামিতিগুলির সাথে লুপ করার সময়
    • ঘুম "বিরতি"
    • যদি বেশ কয়েকটি বার সময় দেওয়া হয়ে থাকে, তবে এটি পৌঁছানো অবধি কমবে var

অতএব:

loop() {
    local i=2 t=1 cond

    [ -z ${1//[0-9]/} ] && i=$1 && shift
    [ -z ${1//[0-9]/} ] && t=$1 && shift && cond=1
    while [ $t -gt 0 ]; do 
        sleep $i
        [ $cond ] && : $[--t]
        $@
    done
}

দ্রষ্টব্য: এটি ভাসমানগুলির সাথে কাজ করে না, sleepসেগুলি গ্রহণ করেও ।
ব্যারনসড হয়েছে

2

সোয়াগালের উত্তরে বৈকল্পিক তৈরি করে আমি ক্ষতবিক্ষত করেছি। তার সাথে আপনাকে প্রথম পুনরাবৃত্তির জন্য এক্স সেকেন্ড অপেক্ষা করতে হয়েছিল, আমিও আমার অগ্রভাগে চালিয়ে যাচ্ছি ..

./foo.sh;while sleep 1; do (./foo.sh) ; done

1

দ্রুত, নোংরা এবং বুট করা সম্ভবত বিপজ্জনক তবে আপনি যদি দুঃসাহসিক হয়ে থাকেন এবং আপনি কী করছেন তা যদি জানেন তবে এটি এতে রাখুন repeat.shএবংchmod 755

while true
do 
    eval $1 
    sleep $2 
done

সাথে এটি চাওয়া ./repeat.sh <command> <interval>

আমার স্পাইডি ইন্দ্রিয় বলে যে এটি সম্ভবত এটি করার একটি খারাপ উপায়, আমার স্পাইডি ইন্দ্রিয়টি কি ঠিক?


8
Eval !? কিসের জন্য? sleep $1; shift; "$@"বা অনুরূপ আরও ভাল হবে।
মিকেল

ডুনো কেন এই -2। ইওল অতিরিক্ত ওষুধ খাওয়ানো হতে পারে ... যখন আপনার প্রয়োজন হয় except ইভাল আপনাকে কমান্ড লাইনে পুনঃনির্দেশের মতো জিনিস পেতে দেয়।
জোহান

1

আপনি init থেকে স্ক্রিপ্ট চালাতে পারেন (/ etc / inittab এ একটি লাইন যুক্ত করা)। এই স্ক্রিপ্টটি আপনার কমান্ডটি চালাতে হবে, আপনি আবার স্ক্রিপ্টটি চালা না হওয়া পর্যন্ত অপেক্ষা করতে চান, এবং এটি থেকে প্রস্থান করতে হবে। প্রস্থানটি প্রস্থান করার পরে আবার আপনার স্ক্রিপ্ট শুরু করবে।


1

এক মিনিটেরও কম সময়ের ব্যবধান (20 সেকেন্ডের উদাহরণ) সহ ক্রন্টব থেকে কোনও কাজের পুনরাবৃত্তি করার সহজ উপায়:

crontab: * * * * * স্ক্রিপ্ট.শ

script.sh:

#!/bin/bash
>>type your commands here.

sleep 20
>>retype your commands here.

sleep 20
>>retype your commands here.

1

আপনি শেল থেকে পাইথন ইন্টারপ্রেটার থেকে শক্তি পেতে পারেন।

python3 -c "import time, os
while True:
    os.system('your command')
    time.sleep(5)

আপনি যে কোনও সময় পাঁচ (সেকেন্ড) প্রতিস্থাপন করুন।

মনোযোগ দিন: শেল ইনপুট ফিরিয়ে আনতে SHIFT + ENTER ব্যবহার করুন। এবং লুপের সময় প্রতিটি লাইনে 4 স্পেসইসি ইনডেন্ট টাইপ করতে ভুলবেন না ।


মনে রাখবেন যে, pythonএর os.system()কমান্ড লাইন ব্যাখ্যা করার জন্য একটি শেল executes, তাই invoking pythonচালানোর জন্য একটি কমান্ড পর্যায়ক্রমে একটি বিট Overkill একটি লুপ শাঁস চালানোর জন্য। আপনি শেল সমস্ত কিছু করতে পারে।
স্টাফেন চেজেলাস

আমি আপনার সাথে একমত. তবে আপনি প্রতিটি লুপে বর্ণিত হিসাবে 5 সেকেন্ডের ঘুম আছে। সুতরাং একটি নতুন শেল শুরু করা থেকে অতিরিক্ত ব্যয় উপেক্ষা করা যেতে পারে। যদি এই ব্যয়টি প্রত্যাশার চেয়ে বেশি সময় করে দেয় তবে আপনি প্রয়োজন মতো কিছু ঘুমের সময় কমিয়ে আনতে পারেন।
pah8J

0

এই সমাধানটি ম্যাকোএসএক্স 10.7 এ কাজ করে। এটি আশ্চর্যজনকভাবে কাজ করে।

bash -c 'while [ 0 ]; do \
      echo "I will not automate this punishment in absurdum."; done'

আমার ক্ষেত্রে

bash -c 'while [ 0 ]; do ls; done'

অথবা

bash -c 'while [ 0 ]; do mv "Desktop/* Documents/Cleanup"; done'

ক্রমাগত আমার ডেস্কটপ পরিষ্কার করতে।


1
আপনি কি sleepসেখানে একটি আদেশ আছে মানে ?
কিথ থম্পসন

4
while [ 0 ]অসীম লুপ লেখার একটি বিজোড় উপায়; এটি কাজ করে কারণ testকমান্ডটি (এটিও পরিচিত [) খালি খালি স্ট্রিংটিকে সত্য হিসাবে বিবেচনা করে। while : ; do ... ; doneআরও মূর্তিযুক্ত, বা আপনি যদি পছন্দ করেন আপনি ব্যবহার করতে পারেন while true ; do ... ; done
কিথ থম্পসন

0

আপনি এই পুনরাবৃত্ত ফাংশন উত্স হতে পারে:

#!/bin/bash
ininterval () {
    delay=$1
    shift
    $*
    sleep $delay
    ininterval $delay $*
}

বা একটি যুক্ত করুন:

ininterval $*

এবং স্ক্রিপ্ট কল।


0

একটি কনসোল উইন্ডোতে বার বার কমান্ড চালানোর জন্য আমি সাধারণত এরকম কিছু চালাই:

while true; do (run command here); done

এটি একাধিক কমান্ডের জন্যও কাজ করে, উদাহরণস্বরূপ, একটি কনসোল উইন্ডোতে ক্রমাগত আপডেট হওয়া ঘড়ি প্রদর্শন করতে:

while true; do clear; date; sleep 1; done


ডাউনটা কেন? টার্মিনাল উইন্ডোতে উদাহরণটি অনুলিপি করে আটকানোর মাধ্যমে আপনি এটি একটি কার্যক্ষম সমাধান দেখতে পাচ্ছেন।
থমাস ব্র্যাট

আমি মনে করি আপনি ভোট পেয়েছেন কারণ এটি কিছুটা বিপজ্জনক এবং সিপিইউ গ্রাস করে।
ojblass

0
#! /bin/sh

# Run all programs in a directory in parallel
# Usage: run-parallel directory delay
# Copyright 2013 by Marc Perkel
# docs at http://wiki.junkemailfilter.com/index.php/How_to_run_a_Linux_script_every_few_seconds_under_cron"
# Free to use with attribution

if [ $# -eq 0 ]
then
   echo
   echo "run-parallel by Marc Perkel"
   echo
   echo "This program is used to run all programs in a directory in parallel" 
   echo "or to rerun them every X seconds for one minute."
   echo "Think of this program as cron with seconds resolution."
   echo
   echo "Usage: run-parallel [directory] [delay]"
   echo
   echo "Examples:"
   echo "   run-parallel /etc/cron.20sec 20"
   echo "   run-parallel 20"
   echo "   # Runs all executable files in /etc/cron.20sec every 20 seconds or 3 times a minute."
   echo 
   echo "If delay parameter is missing it runs everything once and exits."
   echo "If only delay is passed then the directory /etc/cron.[delay]sec is assumed."
   echo
   echo 'if "cronsec" is passed then it runs all of these delays 2 3 4 5 6 10 12 15 20 30'
   echo "resulting in 30 20 15 12 10 6 5 4 3 2 executions per minute." 
   echo
   exit
fi

# If "cronsec" is passed as a parameter then run all the delays in parallel

if [ $1 = cronsec ]
then
   $0 2 &
   $0 3 &
   $0 4 &
   $0 5 &
   $0 6 &
   $0 10 &
   $0 12 &
   $0 15 &
   $0 20 &
   $0 30 &
   exit
fi

# Set the directory to first prameter and delay to second parameter

dir=$1
delay=$2

# If only parameter is 2,3,4,5,6,10,12,15,20,30 then automatically calculate 
# the standard directory name /etc/cron.[delay]sec

if [[ "$1" =~ ^(2|3|4|5|6|10|12|15|20|30)$ ]]
then
   dir="/etc/cron.$1sec"
   delay=$1
fi

# Exit if directory doesn't exist or has no files

if [ ! "$(ls -A $dir/)" ]
then
   exit
fi

# Sleep if both $delay and $counter are set

if [ ! -z $delay ] && [ ! -z $counter ]
then
   sleep $delay
fi

# Set counter to 0 if not set

if [ -z $counter ]
then
   counter=0
fi

# Run all the programs in the directory in parallel
# Use of timeout ensures that the processes are killed if they run too long

for program in $dir/* ; do
   if [ -x $program ] 
   then
      if [ "0$delay" -gt 1 ] 
      then
         timeout $delay $program &> /dev/null &
      else
         $program &> /dev/null &
      fi
   fi
done

# If delay not set then we're done

if [ -z $delay ]
then
   exit
fi

# Add delay to counter

counter=$(( $counter + $delay ))

# If minute is not up - call self recursively

if [ $counter -lt 60 ]
then
   . $0 $dir $delay &
fi

# Otherwise we're done

0

সহ zshএবং একটি sleepবাস্তবায়ন যা ভাসমান-পয়েন্ট আর্গুমেন্টগুলি গ্রহণ করে:

typeset -F SECONDS=0 n=0
repeat 100 {cmd; sleep $(((n+=3) - SECONDS))}

বা এর জন্য forever:

for ((;;)) {cmd; sleep $(((n+=3) - SECONDS))}

আপনার যদি sleepভাসে সমর্থন করে না, আপনি সবসময় এটি একটি মোড়কের প্রায় হিসাবে পুনরায় সংজ্ঞায়িত করতে zshএর zselectbuiltin:

zmodload zsh/zselect
sleep() zselect -t $((($1 * 100) | 0))

-1

... আমি ভাবছি এই সমস্যাটি সমাধান করার সময় কত জটিল সমাধান তৈরি করা যায়।

এটি এত সহজ হতে পারে ...

open /etc/crontab 

ফাইলের শেষে 1 পরের লাইনটি এখানে রাখুন:

*/NumberOfSeconds * * * * user /path/to/file.sh

আপনি যদি প্রতি 1 সেকেন্ডে কিছু চালাতে চান তবে কেবল সেখানে রাখুন:

*/60 * * * * root /path/to/file.sh 

where that file.sh could be chmod 750 /path/to/file.sh

এবং সেই ফাইলটির ভিতরে থাকা উচিত sh

#!/bin/bash 
#What does it do
#What is it runned by

your code or commands

এবং সব শেষ!

উপভোগ করুন!


6
এটি সঠিক নয়। * / 60 প্রতি 60 মিনিট চলবে এবং * / 5, উদাহরণস্বরূপ, প্রতি 5 মিনিটে।
মিকা 17

1
crontab- এ সেকেন্ডের অনুমতি নেই
GAD3R

ভুল বিষ্ঠা দিয়ে উত্তর দেওয়ার আগে আপনার স্টাফ পরীক্ষা করুন।
sjas

-1
until ! sleep 60; do echo $(date); command; command; command; done

আমার জন্য কাজ কর.

  1. আমার ঠিক 60 সেকেন্ডে এটির দরকার নেই
  2. "ওয়াচ" সমস্ত সিস্টেমে কমান্ড দেখে না
  3. "দেখুন" কেবল একটি কমান্ড নিতে পারে (বা একটি স্ক্রিপ্ট ফাইল)
  4. শরীরের পরিবর্তে ঘুমের অবস্থাটি লুপটিকে আরও ভাল বাধাপ্রাপ্ত করে তোলে (সুতরাং স্ট্যাকওভারফ্লোতে অনুরূপ প্রশ্নের উত্তরে দাবি claim দুর্ভাগ্যবশত আমি এই মুহুর্তে এটি খুঁজে পেতে পারি)
  5. আমি বিলম্বের আগে একবার এটি সম্পাদন করতে চাই, তাই আমি কিছুক্ষণ বাদে ব্যবহার করি

আমি কেবল লক্ষ্য করেছি যে "অবধি" আপাতদৃষ্টিতে প্রথম পুনরাবৃত্তির আগে ঘুমকে কার্যকর করে। ব্যাশ এ লুপ শেষে শর্তটি রাখার কোন উপায় আছে?
তিতাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.