How can I repeat a command every interval of time , so that it will allow me to run commands for checking or monitoring directories ?
There is no need for a script, i need just a simple command to be executed in terminal.
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.
Sign up to join this communityYou can use watch
command, watch is used to run any designated command at regular intervals.
Open Terminal and type:
watch -n x <your command>
change x to be the time in seconds you want.
For more help using the watch
command and its options, run man watch
or visit this Link.
For example : the following will list, every 60s, on the same Terminal, the contents of the Desktop directory so that you can know if any changes took place:
watch -n 60 ls -l ~/Desktop
watch -n 1 'echo $COLUMNS'
and watch -n 1 echo $COLUMNS
when resizing your terminal - the former is expanded every second, but the latter is expanded only once before watch
starts.
watch
with "history enabled" type command? I love using watch
, but sometimes I'd prefer to see a log of previous executions as well, instead of just the last one. And yes, I know I can use scripting (while true
) to accomplish this, but using the watch
utilitiy is so much cleaner!
You can also use this command in terminal, apart from nux's answer:
while true; do <your_command>; sleep <interval_in_seconds>; done
Example:
while true; do ls; sleep 2; done
This command will print the output of ls
at an interval of 2 sec.
Use Ctrl+C to stop the process.
There are few drawbacks of watch
:
watch
will interpret ANSI color sequences passing escape characters using -c
or --color
option. For example output of pygmentize
will work but it will fail for ls --color=auto
.In the above circumstances this may appear as a better option.
watch
is good in most cases. That is why I mentioned "apart from nux's answer" at the beginning. But there are few problems with watch
for example One can not use any aliased commands with watch
. Take for example ll
which is aliased to ls -laF
but can not be used with watch
. Also in case if the output of any command is quite long you will be in trouble in scrolling using watch
. In these few special cases this answer may appear a better option.
Mar 6, 2014 at 17:25
watch
, it keeps the command history.
Feb 14, 2017 at 18:31
watch
is that if I resize my terminal window, it runs the command again.
Sep 25, 2019 at 20:14
Just wanted to pitch in to sourav c.'s and nux's answers:
While watch
will work perfectly on Ubuntu, you might want to avoid that if you want your "Unix-fu" to be pure. On FreeBSD for example, watch
is a command to "snoop on another tty line".
while true; do command; sleep SECONDS; done
also has a caveat: your command might be harder to kill using Ctrl+C. You might prefer:
while sleep SECONDS; do command; done
It's not only shorter, but also easier to interrupt. The caveat is that it will first sleep, then run your command, so you'll need to wait some SECONDS
before the first occurrence of the command will happen.
sleep
in the while
loop? I couldn't find any difference, Ctrl+C broke the loop instantly no matter what.
command
and sleep
and only break if you kill true
.
Sounds like the ideal task for the cron
daemon which allows for running periodic commands. Run the crontab -e
command to start editing your user's cron configuration. Its format is documented in crontab(5). Basically you have five time-related, space-separated fields followed by a command:
The time and date fields are:
field allowed values
----- --------------
minute 0-59
hour 0-23
day of month 1-31
month 1-12 (or names, see below)
day of week 0-7 (0 or 7 is Sunday, or use names)
For example, if you would like to run a Python script on every Tuesday, 11 AM:
0 11 * * 1 python ~/yourscript.py
There are also some special names that replace the time, like @reboot
. Very helpful if you need to create a temporary directory. From my crontab (listed with crontab -l
):
# Creates a temporary directory for ~/.distcc at boot
@reboot ln -sfn "$(mktemp -d "/tmp/distcc.XXXXXXXX")" "$HOME/.distcc"
cron
runs behind the scenes rather than in the terminal
Dec 15, 2014 at 19:22
you can use crontab. run the command crontab -e
and open it with your preferred text editor, then add this line
*/10 * * * * /path-to-your-command
This will run your command every 10 minutes
* */4 * * * /path-to-your-command
This will run your command every 4 hours
$ ..some command...; for i in $(seq X); do $cmd; sleep Y; done
X number of times to repeat.
Y time to wait to repeat.
Example :
$ echo; for i in $(seq 5); do $cmd "This is echo number: $i"; sleep 1;done
If you are monitoring the file system, then inotifywait
is brilliant and certainly adds less load on your system.
Example :
In 1st terminal type this command :
$ inotifywait .
Then in 2nd terminal, any command that affects the current directory,
$ touch newfile
Then in original terminal inotifywait will wake up and report the event
./ CREATE newfile2
Or in a loop
$ while true ; do inotifywait . ; done
Setting up watches.
Watches established.
./ OPEN newfile2
Setting up watches.
Watches established.
./ OPEN newfile2
Setting up watches.
Watches established.
./ DELETE newfile
Setting up watches.
Watches established.
./ CREATE,ISDIR newdir
Setting up watches.
Watches established.
grep something InALogFile|less
is that a script ?
-m
to continually monitor without a loop.
You can create your own repeat
command doing the following steps; credits here:
First, open your .bash_aliases
file:
$ xdg-open ~/.bash-aliases
Second, paste these lines at the bottom of the file and save:
repeat() {
n=$1
shift
while [ $(( n -= 1 )) -ge 0 ]
do
"$@"
done
}
Third, either close and open again your terminal, or type:
$ source ~/.bash_aliases
Et voilà ! You can now use it like this:
$ repeat 5 echo Hello World !!!
or
$ repeat 5 ./myscript.sh
Another concern with the "watch" approach proposed above is that it does display the result only when the process is done. "date;sleep 58;date" will display the 2 dates only after 59 seconds... If you start something running for 4 minutes, that display slowly multiple pages of content, you will not really see it.
On the other hand, the concern with the "while" approach is that it doesn't take the task duration into consideration.
while true; do script_that_take_between_10s_to_50s.sh; sleep 50; done
With this, the script will run sometime every minutes, sometime might take 1m40. So even if a cron will be able to run it every minutes, here, it will not.
So to see the output on the shell as it's generated and wait for the exact request time, you need to look at the time before, and after, and loop with the while.
Something like:
while ( true ); do
echo Date starting `date`
before=`date +%s`
sleep `echo $(( ( RANDOM % 30 ) + 1 ))`
echo Before waiting `date`
after=`date +%s`
DELAY=`echo "60-($after-$before)" | bc`
sleep $DELAY
echo Done waiting `date`
done
This will output this:
As you can see, the command runs every minutes:
Date starting Mon Dec 14 15:49:34 EST 2015
Before waiting Mon Dec 14 15:49:52 EST 2015
Done waiting Mon Dec 14 15:50:34 EST 2015
Date starting Mon Dec 14 15:50:34 EST 2015
Before waiting Mon Dec 14 15:50:39 EST 2015
Done waiting Mon Dec 14 15:51:34 EST 2015
So just replace the "sleep echo $(( ( RANDOM % 30 ) + 1 ))
" command with what ever you want and that will be run, on the terminal/shell, exactly every minute. If you want another schedule, just change the "60" seconds with what ever you need.
Shorter version without the debug lines:
while ( true ); do
before=`date +%s`
sleep `echo $(( ( RANDOM % 30 ) + 1 ))` # Place you command here
after=`date +%s`
DELAY=`echo "60-($after-$before)" | bc`
sleep $DELAY
done