70

I want to write some image downloader and assign it on bash. What I have and what I need:

I have:

  1. Command, which works fine (something like wget http://mywebcam.com/image.jpg -O /var/cam/Image.jpg)
  2. Root rights

  3. Fast Internet line between my server and my webcam

What I need:

Download image from camera every second*(sleep 1?)* and rewrite it localy (my command do it well) Run this script at once and don't worry about restart (I think I need to create file with bash commands and run it once + set crontab work "on reboot" to this file, right?)

Maybe there's someone who knows what should I to do?

jww
  • 97,681
  • 90
  • 411
  • 885
Egor Sazanovich
  • 4,979
  • 5
  • 23
  • 37

3 Answers3

141

If you want to run a command at one second intervals (one second between the end of one command and the beginning of the next, which is not the same as running every second), just do:

while sleep 1; do cmd; done

If you want that to start on reboot, the method will depend on your system.

Note that it is certainly possible to start an execution every second rather than running at one second intervals, but I suspect that is not actually what you want. In addition, there are inherent risks with doing so. For example, if the system gets sluggish and the command starts taking longer than one second to run you may run out of resources.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • I have CentOS on my server. Is this right way to add it to crontab? – Egor Sazanovich Feb 15 '12 at 19:17
  • I am not familiar with CentOS, but cron is not the way to go. Instead, try adding a line to /etc/rc.local – William Pursell Feb 15 '12 at 20:13
  • I've used this to fix the filesystem bug that I have with my Virtualbox Linux VM that uses my Windows' D:\www\ as it's Apache root folder. – Henry van Megen Feb 06 '14 at 12:25
  • Usually I'd cringe at the thought of doing something every second, but this is the right way. If you use any method that actually runs it every second you will run into a growing resource problem. Say the command takes 1-2s to run. Every second you'd spawn a process that runs for 1-2s. As these continue to grow, they'll take longer to finish and eventually you'd end up crawling the system to a halt. Put this in ``/etc/init.d/rc.local`` for centos and make sure you put logging for ``do cmd >/var/log/mything 2>&1`` – Marc Young Oct 22 '15 at 12:53
  • After the command's output overflows the screen's line limit the refereshment of the periodic command may not be distinguished. Though the command's period is two secons, you can use while sleep 1; do cmd; sleep 1; clear; done. It shows the output, then clears the screen, and then show the output, so on. This way you are sure that the command's running. – Gürol Canbek Jan 10 '17 at 16:25
  • 3
    Another way to distinguish the output is to simply add a timestamp: `while sleep 1; do date; cmd; done` Or maybe a banner: `while sleep 1; do echo; echo "**********************"; date; cmd; done` – William Pursell Mar 11 '17 at 14:06
  • Note that on some systems, `sleep` takes a floating-point parameter, which lets you run commands more than once per second. I found this useful for monitoring free memory via /proc/meminfo while debugging a crash. – Adam Haun Apr 04 '18 at 22:49
85

The command watch will do this for you straight up. It also displays the result in a nice way.

$ watch -n 1 date

Substitute date for your command. The -n option specifies the interval in seconds.

while
  • 3,602
  • 4
  • 33
  • 42
  • 7
    Perfect! If you use a command with pipes, just put quotes around it: `watch -n 1 "du -hs * | sort -h | grep nodes"` – Matthias Dunkel Nov 29 '18 at 14:07
  • 2
    And to turn off the header for redirects to log `watch -t -n 1 "du -hs * | sort -h | grep nodes >> nodes.log"` – hobs Jan 13 '19 at 17:53
1

To add my two cents to this... If the cron's one minute interval is too long for you, you can take advantage of the systemd's capability to restart services repeatedly.

[Unit]
Description=Poll something each second

[Service]
Type=simple
ExecStart=/opt/poller/poll.sh
Restart=always
RestartSec=1
StartLimitInterval=0

[Install]
WantedBy=multi-user.target

I know it's a messy and sort of "never ever do this" approach. But it works perfectly an is fairly simple to set up.

Newerth
  • 449
  • 2
  • 12