I need to write me 1st cron script...

Posted:
in Genius Bar edited January 2014
I need to write a simple cron script that will run 5 times a day, everyday, for 2 weeks:





1) Run a traceroute test to a particular address (i.e.; address.domain.com) (max 30 hops)



2) Run a ping test to the same address (5 packets is enough)



3) Output the data to a text file with the time and date.



4) Repeat 5 times a day (start at 6 AM and run every 3 hours until 5 itterations have completed)





After 2 weeks, I want a nice "log" of my tests in a single file





(The ping/traceroute address will be the same over the entire test.)

Comments

  • Reply 1 of 19
    willoughbywilloughby Posts: 1,457member
    Are you asking for someone to write the entire thing for you or is there a particular part that you need help with?



    Do you need help with setting up cron or the actual script itself?
  • Reply 2 of 19
    thuh freakthuh freak Posts: 2,664member
    what i'd suggest is breaking it into two parts: a shell script to do all the action, and an addition in ur crontab to execute the script.



    for the shell script you could do:

    Code:


    #!/bin/sh

    /usr/bin/uptime >> /path/to/saved/file

    /usr/sbin/traceroute "address" >> /path/to/saved/file

    /sbin/ping -c 5 "address" >> /path/to/saved/file





    where '/path/to/saved/file' is a unix style path to the log file where you want it (like "/User/[userName]/mylogfile.txt"). save that script somewhere, like /usr/local/bin, and give it execute permissions.



    and, then for cron you need to add a few lines:

    Code:


    0 6 * * * [username] /path/to/above/script

    0 9 * * * [username] /path/to/above/script

    0 12 * * * [username] /path/to/above/script

    0 15 * * * [username] /path/to/above/script

    0 18 * * * [username] /path/to/above/script





    the zeroes in the first column are for 0 minutes passed the hour, the second number per line is the hour of the day (24h clock), the stars mean every day of every month, and every day of the week. and your username shouldn't really have the braces.



    the only thing this thing leaves standing is after two weeks you have to remove the lines from crontab, and (optionally) get rid of the shell script.
  • Reply 3 of 19
    dstranathandstranathan Posts: 1,717member
    Cool, thanks



    Here is my script, what do ya think?





    I have 1 minor problem:



    1) The beginning of the traceroute's output ("traceroute to apple.com (17.254.3.183), 30 hops max, 40 byte packets") gets dumped to the terminal (standard output) instead of the file. Why? Eveything else gets dumped to the file just fine. why?



    2) How do I echo blank lines? I would like some nice breaks between iterations.



    3) What's the diff between /bin and /sbin? I think your paths in the example above were wrong, so I found the shell commands elsewhere. Is that OK? See below...















    #!/bin/sh

    #

    #

    # Display time here:

    #

    /bin/date >> /Users/Dan/networktest.txt

    #

    #

    # Begin traceroute code here:

    echo "run traceroute" >> /Users/Dan/networktest.txt

    /usr/sbin/traceroute apple.com >> /Users/Dan/networktest.txt

    echo "end traceroute" >> /Users/Dan/networktest.txt

    #

    #

    # Begin ping code here:

    #

    #

    /usr/bin/time >> /Users/Dan/networktest.txt

    echo "run ping" >> /Users/Dan/networktest.txt

    /sbin/ping -c 5 apple.com >> /Users/Dan/networktest.txt

    echo "end ping" >> /Users/Dan/networktest.txt

    #

    #

    echo "-------------------------------------" >> /Users/Dan/networktest.txt

    echo "" >> /Users/Dan/networktest.txt







    What do ya think? Can you run it for me and see if it can be made better?



    Will I have problems appending all my iterations to a single file? It seems OK to me. I was affraid it would overwrite the file each times, but it concatenats (appends), which is what I want.
  • Reply 4 of 19
    gargoylegargoyle Posts: 660member
    Quote:

    1) The beginning of the traceroute's output ("traceroute to apple.com (17.254.3.183), 30 hops max, 40 byte packets") gets dumped to the terminal (standard output) instead of the file. Why? Eveything else gets dumped to the file just fine. why?



    Hmm interesting, that happens on my linux webserver too. Will have to lookup the docs and see if there is an option for that.



    Quote:

    2) How do I echo blank lines? I would like some nice breaks between iterations.



    echo "" >>test.txt



    Quote:

    3) What's the diff between /bin and /sbin? I think your paths in the example above were wrong, so I found the shell commands elsewhere. Is that OK? See below...



    http://www.tuxfiles.org/linuxhelp/linuxdir.html



    Quote:

    What do ya think? Can you run it for me and see if it can be made better?



    Not sure about darwin, (iMac is on order) but linux traceroute will keep running forever until you terminate it. ctrl-c.



    Quote:

    Will I have problems appending all my iterations to a single file? It seems OK to me. I was affraid it would overwrite the file each times, but it concatenats (appends), which is what I want.



    [/QUOTE]



    No, you will not have any problems with appending... Unless you forget about it and end up with a 4gig file!!!



    The ">>" in the middle of the lines is what called a redirector. You are redirecting the output to a file instead of the screen.



    >> = Append

    > = overwrite
  • Reply 5 of 19
    dstranathandstranathan Posts: 1,717member
    You guys are very helpful. I owe the guys and gals at Appleinsider big time!



    Thanks again for the great input and feedback!



    Gargoyle: I think the default setting for the traceroute command in OS X is 30 hops. I don't think it will run forever, right? Or is there some other option I need to add to my traceroute command to prevent it from running forever?
  • Reply 6 of 19
    gargoylegargoyle Posts: 660member
    ah yes, that would be the "30 hops max" bit.



    /me puts on his reading glasses.
  • Reply 7 of 19
    thuh freakthuh freak Posts: 2,664member
    before i started writing the shell part, i noted to myself that i should redirect both stdout and stderr, but then i forgot. incase that didn't make any sense, i'll try to clarify with the following: each program automatically opens 2 links to (usually the same) pipe. stdout (standard output) and stderr (standard error output). in sh, bash and similar shells (tho not *csh), you can redirect stderr with '2>' instead of '>'. and furthermore, you can force stderr to follow stdout even if you redirect it, with '2>&1'.



    so for your lines, whenever you have

    "/x/y/z >> /a/b"

    change to

    "/x/y/z >> /a/b 2>&1"



    example:

    /bin/date >> /Users/Dan/networktest.txt

    (to...) /bin/date >> /Users/Dan/networktest.txt 2>&1





    also, the diff between /usr/bin and /usr/sbin is well, they are both folders on your computer. they both house programs, i think sbin is more for services or something. the paths of the programs i mentioned, i checked, but you can search your computer for the files if you aint sure (`ls /path/to/file`).
  • Reply 8 of 19
    dstranathandstranathan Posts: 1,717member
    so the 2>&1 will put the standard output and any error messages into the same file?



    What if I ran the script without the 2>&1 and I got an error at some point? Where does the error "go"? Would it halt my script or muck up the output file?



    Will the 2>&1 keep my scripts running even if the script errors out?



    I guess I need more info on what the 2>&1 will do for me. Sell me on the idea! :0)
  • Reply 9 of 19
    thuh freakthuh freak Posts: 2,664member
    perhaps i didn't explain it well in the first run-through. in sh, you can redirect stderr to follow stdout. here's the contrast, in normal execution they point to the same place; but when you redirect with '>', stdout goes elsewhere, while stderr keeps pointing at the terminal window. using '2>&1' redirects '2' (stderr) to the follow the file referred to by id '1'. so, however you direct stdout (1) to go, stderr (2) will follow. normally, if you do:

    /bin/program > /some/file 2> /some/file

    stdout will clobber the stderr, and not save it to the file. but:

    /bin/program > /some/file 2>&1

    cues the stdout and stderr outputs to look appropriately interspliced, as they would in a terminal, in the file. effectively treating the program's attempts at writing to either stderr or stdout as pointing to the same file pointer.



    so, when you say:

    Quote:

    The beginning of the traceroute's output (...) gets dumped to the terminal (standard output) instead of the file.



    thats not actually stdout, its probably stderr (or some dirty hacking on the part of the traceroute programmers , but i doubt that). we can bet on it being stderr, especially since i confirmed it on my terminal.



    the '2>&1' will not affect execution or change how the program actually runs in any way. it just makes sure that stderr is taken care of along with stdout, in a manner of output that is expected. if you omit '2>&1', stderr will not be redirected, so it will go to its regular location. but, since cron is a daemon (daemon means a program that has no input, no output), the default location for its sub processes' (aka your shell script's) stdout/stderr is to /dev/null (where the output is safely destroyed). if you don't put '>2&1' any messages that may normally be put onto stderr will effectively be destroyed but will NOT halt the program themself (and also will NOT halt the script). but, if the messages attempted onto stderr in some way explained any impending doom of a program, then u may not know why or what happened or caused the problem. the mesages themselves, where ever they happen to be directed, wll not cause the demise of a program nor a script incharge of running programs. basically, the reason you would use '2>&1' along with '>> /Users/Dan/networktest.txt' is because the file (networtest.txt) will look more like the terminal would, had you run the program without redirection.



    (looking over my post: i write entirely too much. i hope i didn't confuse you further with all my inane words.)
  • Reply 10 of 19
    dstranathandstranathan Posts: 1,717member
    Thuh Freak



    No, not at all, I appreciate the details. I used to code in VMS a LONG time agao, and I am so rusty that it's pathetic. Im glad I have found people like you who are patient and helpful.
  • Reply 11 of 19
    dstranathandstranathan Posts: 1,717member
    OK, this is the hard part: UDP vs TCP



    From inside my LAN, Using OS X, I can't run traceroute to the desired test site out on the Internet. I can't run tracerout through my firewall via certain ports. I can ping fine, just not traceroute. BUT:



    From my LAN, using Windows NT, 2K and XP, I CAN run the "tracert" command and get through my firewall just fine.



    I scratched my head, read the OS X man pages, and was stumped, but THEN...



    I decided to run a traceroute tool from good old OS 9 (using the "What Route" app that Apple shipped with OS 9). Sure enough, it failed just like OS X did. UNTIL I tweaked a setting in the What Route GUI! I turned OFF this setting:



    "Use UDP Traceroute"



    BAM! Now it works in OS 9! Hmmmm...





    Question: So how to I include this option in my OS X traceroute command? I don't see it in the man pages...





    Any thoughts?
  • Reply 12 of 19
    dstranathandstranathan Posts: 1,717member
    Regarding the location of the cron file I need to edit:



    Where is it exactly? I see a few cron files and dirs all over the place. I wanna make sure I'm in the correct file. I sound lame, I know. Sorry. :0)



    I have built a cron file, I just don't know where to put it, and how to "call" it into active duty!



    Oh, I'm in OS X 10.1.5 BTW...





    DOH!
  • Reply 13 of 19
    dstranathandstranathan Posts: 1,717member
    OK, I figured out how to edit the ROOT crontab and run my script as root, which is fine. I would love to know how to have a cron tab as a "normal" user, and not have to edit the /etc/crontab file...
  • Reply 14 of 19
    dstranathandstranathan Posts: 1,717member
    Heres the /etc crontab:



    Here is the crontab I am using (in /etc/crontab)





    # $NetBSD: crontab,v 1.13 1997/10/26 13:36:31 lukem Exp $

    #

    # /etc/crontab - root's crontab

    #

    SHELL=/bin/sh

    PATH=/bin:/sbin:/usr/bin:/usr/sbin

    HOME=/var/log



    (I am not showing you a couple system cron jobs that are located here , left out for space reasons...)





    # network-report script

    0\t6\t*\t*\t*\troot\t/usr/local/bin/network-report

    0\t9\t*\t*\t*\troot\t/usr/local/bin/network-report

    0\t12\t*\t*\t*\troot\t/usr/local/bin/network-report

    0\t15\t*\t*\t*\troot\t/usr/local/bin/network-report

    0\t18\t*\t*\t*\troot\t/usr/local/bin/network-report



    -------------------------------------------





    1) What do these lines reference?



    SHELL=/bin/sh

    PATH=/bin:/sbin:/usr/bin:/usr/sbin

    HOME=/var/log



    I ask because my actual script is in /usr/local/bin. Is that OK?







    2) Should my crontab say this:



    version a)



    # network-report script

    0\t6\t*\t*\t*\troot\tsh /usr/local/bin/network-report

    0\t9\t*\t*\t*\troot\tsh /usr/local/bin/network-report

    0\t12\t*\t*\t*\troot\tsh /usr/local/bin/network-report

    0\t15\t*\t*\t*\troot\tsh /usr/local/bin/network-report

    0\t18\t*\t*\t*\troot\tsh /usr/local/bin/network-report



    (note the added "sh" before the path to my script )





    instead of this:



    version b)



    # network-report script

    0\t6\t*\t*\t*\troot\t/usr/local/bin/network-report

    0\t9\t*\t*\t*\troot\t/usr/local/bin/network-report

    0\t12\t*\t*\t*\troot\t/usr/local/bin/network-report

    0\t15\t*\t*\t*\troot\t/usr/local/bin/network-report

    0\t18\t*\t*\t*\troot\t/usr/local/bin/network-report





    I ask because I have seen other crontabs that use the "sh" in the path to their scripts. Do I need it?



    3) What does 10.1.5 have a NetBSD crontab and not a FreeBSD crontab? What does 10.2 have?



    Thanks!
  • Reply 15 of 19
    thuh freakthuh freak Posts: 2,664member
    ok, first, to edit your crontab, i think the preferred method is to run 'crontab -e'. but, as long as you remember which parts of the root tab are yours, and will make sure to clean it out when necessary, it shouldn't matter that its part of root crontab. i'm pretty sure that crontab -e opens up /etc/crontab anyway.



    second, i'm not sure how to make traceroute not try udp. but if you have access to the firewall, you can try opening ports '33434' to '33465'. you can also try using traceroute with the '-p port' option. according to the manpage, you gotta find a series of 30 ports that are not open on the hosts.



    third, the SHELL, PATH, and HOME lines setup the subprocesses' environment. in posix OSes (which linux, unix, windows nt, wn2k and mac os x are), an environment of variables and values is maintained. if you type 'setenv | more' from your *csh shell, or 'set | more' from a sh or bash shell, you can see all the parts of your regular environment. the subprocesses of cron (the actual jobs) don't need to get that whole environment, they just need a few regulars. SHELL refers to shell proram which is running. The PATH variable allow you to type short names (like traceroute, instead of /usr/sbin/traceroute). everytime you type a command, the shell looks in each of the paths (colon delimited) in the PATH variable, and it executes the first one it finds. The HOME variable sets the home location. Many programs look to HOME, so they know where to put preferences; and since cron typically runs scripts which produce logs, they made the home /var/log.



    ok, so the fact that your script is in /usr/local/bin doesn't matter really. If you want to, you can do this: change PATH to the following

    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin

    (added :/usr/local/bin to the end of PATH)

    then, you can take /usr/local/bin/ off of the places in crontab where you refer to ur script (chg /usr/local/bin/network-report to network-report). also, even if a program is within the PATH, you can still write a full path to it.



    next, putting 'sh' infront won't really affect your script. in sh (which is how cron interprets the command to execute ur script), if a file is ascii, then the shell reads the first line of the file to see how to execute it. if the file begins with a line:

    #[optional whitespace]![optional whitespace]/path/to/program/to/execute/the/rest/of/this/file

    for example:

    #!/bin/sh

    that causes any file that starts with that line to be executed using the sh shell.



    now, the last bit i wrote actually only refers to when the shell isn't explicitly told how to handle the file. if you write:

    sh /usr/local/bin/network-test

    the file's first line is not tested, because the shell already knows how to handle the script (ie, with sh). i think its preferable to leave out the sh before the script in crontab, unless u write dirty shell scripts which lack the hash-bang (#!) line. that way, if u learn csh, tcsh, perl or other kinds of scripts, you wont have to break the habit of running them with 'sh script-name'.



    and finally, i dont know too much about the differences between netbsd and freebsd, nor their crontabs. whichever version it happens to be in x.2 shouldn't matter, since ur not depending on the given tab, ur adding in ur own parts.
  • Reply 16 of 19
    dstranathandstranathan Posts: 1,717member
    Thanks man!





    IS there a way to make my default crontab editor pico and not vi?



    I know pico is for weenies, but it does everything I need. I'm not ready for vi yet.
  • Reply 17 of 19
    thuh freakthuh freak Posts: 2,664member
    i actually can't stand vi myself; haven't gotten used to its inane commands. you can change the editor by changing (or adding) the 'EDITOR' variable in the environment. in tcsh (tcsh is the default for osx), or csh or similar shells, you do that with:

    setenv EDITOR pico

    with bash, sh and similars you do:

    export EDITOR=pico;



    then start 'crontab -e' as per usual. when u save (write-out) the file, use the default name. crontab doesn't give the editor the file in place (/etc/crontab), it makes a copy in /tmp/, gives that to the editor, then moves it manually.
  • Reply 18 of 19
    thuh freakthuh freak Posts: 2,664member
    i just realized a something i left out, and a few things i just figured out. first, if you use the '2>&1' it has to be at the end of the related line; it can't go before the '>> /path/to/file'. or else stderr gets redirected to the old stdout, and it won't follow it when u redirect stdout later. next, theres 3 things about crontabs i just realized myself, while playing around with it. you have to have a blank line at the end, or else cron chokes. next, when editing your own crontab (like, if you use 'crontab -e') the username field has to be ommitted. also, ranges and lists can be specified for the time fields; plus, you can skip thru a range by specified amounts. so the several lines of crontab can be cut down to the following:

    0 6-18/3 * * * /usr/local/bin/network-report

    i cut the 'root' out, assuming u'd use this as a personal cron; if u want to keep it in /etc/crontab, you should keep 'root' right before the /usr/local/..... notice the range of '6-18', combined with the '/3' its equivalent to '6,9,12,15,18'.
  • Reply 19 of 19
    dstranathandstranathan Posts: 1,717member
    My cron job is working fine. I love it.



    I learned all about shell scripts and cron jobs!



    WOOt!
Sign In or Register to comment.