{"id":3885,"date":"2018-11-20T03:12:03","date_gmt":"2018-11-20T03:12:03","guid":{"rendered":"https:\/\/www.appservgrid.com\/paw92\/?p=3885"},"modified":"2018-12-07T02:19:00","modified_gmt":"2018-12-07T02:19:00","slug":"schedule-one-time-commands-with-the-unix-at-tool","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw92\/index.php\/2018\/11\/20\/schedule-one-time-commands-with-the-unix-at-tool\/","title":{"rendered":"Schedule One-Time Commands with the UNIX at Tool"},"content":{"rendered":"<p><em>Cron is nice and all, but don&#8217;t forget about its cousin at.<\/em><\/p>\n<p>When I first started using Linux, it was like being tossed into the deep end<br \/>\nof the UNIX pool. You were expected to use the command line heavily along<br \/>\nwith all the standard utilities and services that came with your<br \/>\ndistribution. At lot has changed since then, and nowadays, you can use a<br \/>\nstandard Linux desktop without ever having to open a terminal or use old<br \/>\nUNIX services. Even as a sysadmin, these days, you often are a few layers of<br \/>\nabstraction above some of these core services.<\/p>\n<p>I say all of this to point out that for us old-timers, it&#8217;s easy to take for<br \/>\ngranted that everyone around us innately knows about all the command-line<br \/>\ntools we use. Yet, even though I&#8217;ve been using Linux for 20 years, I<br \/>\nstill learn about new (to me) command-line tools all the time. In this &#8220;Back<br \/>\nto Basics&#8221; article series, I plan to cover some of the command-line tools<br \/>\nthat those new to Linux may never have used before. For those of you who are<br \/>\nmore advanced, I&#8217;ll spread out this series, so you can expect future<br \/>\narticles to be more technical. In this article, I describe how to use<br \/>\nthe at utility to schedule jobs to run at a later date.<\/p>\n<h3>at vs. Cron<\/h3>\n<p>at is one of those commands that isn&#8217;t discussed very much. When<br \/>\npeople talk about scheduling commands, typically cron gets the most<br \/>\ncoverage. Cron allows you to schedule commands to be run on a periodic<br \/>\nbasis. With cron, you can run a command as frequently as every minute or as<br \/>\nseldom as once a day, week, month or even year. You also can define more<br \/>\nsophisticated rules, so commands run, for example, every five minutes, every<br \/>\nweekday, every other hour and many other combinations. System administrators sometimes<br \/>\nwill use cron to schedule a local script to collect metrics every minute or<br \/>\nto schedule backups.<\/p>\n<p>On the other hand, although the at command also allows you to schedule<br \/>\ncommands, it serves a completely different purpose from cron. While cron<br \/>\nlets you schedule commands to run periodically, at lets you schedule<br \/>\ncommands that run only once at a particular time in the future. This<br \/>\nmeans that at fills a different and usually more immediate need<br \/>\nfrom cron.<\/p>\n<h3>Using at<\/h3>\n<p>At one point, the at command came standard on most Linux<br \/>\ndistributions, but<br \/>\nthese days, even on servers, you may find yourself having to<br \/>\ninstall the at package explicitly. Once installed, the easiest<br \/>\nway to use at is to type<br \/>\nit on the command line followed by the time you want the command to run:<\/p>\n<p>$ at 18:00<\/p>\n<p>The at command also can accept a number of different time formats. For<br \/>\ninstance, it understands AM and PM as well as words like &#8220;tomorrow&#8221;, so you<br \/>\ncould replace the above command with the identical:<\/p>\n<p>$ at 6pm<\/p>\n<p>And, if you want to run the same command at that time tomorrow instead:<\/p>\n<p>$ at 6pm tomorrow<\/p>\n<p>Once you press enter, you&#8217;ll drop into an interactive shell:<\/p>\n<p>$ at 6pm tomorrow<br \/>\nwarning: commands will be executed using \/bin\/sh<br \/>\nat&gt;<\/p>\n<p>From the interactive shell, you can enter the command you want to run<br \/>\nat that time. If you want to run multiple commands, press enter after each<br \/>\ncommand and type the command on the new at&gt; prompt. Once you&#8217;re done<br \/>\nentering commands, press Ctrl-D on an empty at&gt; prompt to exit the<br \/>\ninteractive shell.<\/p>\n<p>For instance, let&#8217;s say I&#8217;ve noticed that a particular server has had<br \/>\nproblems the past two days at 5:10am for around five minutes, and so far, I&#8217;m<br \/>\nnot seeing anything in the logs. Although I could just wake up early and log<br \/>\nin to the server, instead I could write a short script that collects data<br \/>\nfrom ps, netstat, tcpdump and other<br \/>\ncommand-line tools for a few minutes, so<br \/>\nwhen I wake up, I can go over the data it collected. Since this is a one-off,<br \/>\nI don&#8217;t want to schedule something with cron and risk forgetting about it<br \/>\nand having it run every day, so this is how I would set it up with<br \/>\nat:<\/p>\n<p>$ at 5:09am tomorrow<br \/>\nwarning: commands will be executed using \/bin\/sh<br \/>\nat&gt;<br \/>\nat&gt; \/usr\/local\/bin\/my_monitoring_script<\/p>\n<p>Then I would press Ctrl-D, and the shell would exit with this output:<\/p>\n<p>at&gt; &lt;EOT&gt;<br \/>\njob 1 at Wed Sep 26 05:09:00 2018<\/p>\n<h3>Managing at Jobs<\/h3>\n<p>Once you have scheduled at jobs, it&#8217;s useful to be able to pull up a list of<br \/>\nall the at jobs in the queue, so you know what&#8217;s running and<br \/>\nwhen. The atq<br \/>\ncommand lists the current at queue:<\/p>\n<p>$ atq<br \/>\n1 Wed Sep 26 05:09:00 2018 a kyle<\/p>\n<p>The first column lists the number at assigned to each job and then lists the<br \/>\ntime the job will be run and the user it will run as. Let&#8217;s say that in<br \/>\nthe above example I realize I&#8217;ve made a mistake, because my script won&#8217;t be able<br \/>\nto run as a regular user. In that case, I would want to use the<br \/>\natrm command<br \/>\nto remove job number 1:<\/p>\n<p>$ atrm 1<\/p>\n<p>If I were to run atq again, I would see that the job no longer exists.<br \/>\nThen I could sudo up to root and use the at command to schedule the job<br \/>\nagain.<\/p>\n<h3>at One-Liners<\/h3>\n<p>Although at supports an interactive mode, you also can pipe commands to it all<br \/>\non one line instead. So, for instance, I could schedule the above job with:<\/p>\n<p>$ echo \/usr\/local\/bin\/my_monitoring_script | at 5:09am tomorrow<\/p>\n<h3>Conclusion<\/h3>\n<p>If you didn&#8217;t know that at existed, you might find yourself coming up with<br \/>\nall sorts of complicated and convoluted ways to schedule a one-off job. Even<br \/>\nworse, you might need to set an alarm clock so you can wake up extra early<br \/>\nand log in to a problem server. Of course, if you don&#8217;t have an alarm clock,<br \/>\nyou could use at:<\/p>\n<p>$ echo &#8220;aplay \/home\/kyle\/alarm.wav&#8221; | at 7am tomorrow<\/p>\n<p><a href=\"https:\/\/www.linuxjournal.com\/content\/schedule-one-time-commands-unix-tool\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cron is nice and all, but don&#8217;t forget about its cousin at. When I first started using Linux, it was like being tossed into the deep end of the UNIX pool. You were expected to use the command line heavily along with all the standard utilities and services that came with your distribution. At lot &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw92\/index.php\/2018\/11\/20\/schedule-one-time-commands-with-the-unix-at-tool\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Schedule One-Time Commands with the UNIX at Tool&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3885","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/3885","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/comments?post=3885"}],"version-history":[{"count":1,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/3885\/revisions"}],"predecessor-version":[{"id":4620,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/3885\/revisions\/4620"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/media?parent=3885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/categories?post=3885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/tags?post=3885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}