Announcement

Collapse
No announcement yet.

Scripting data and time functrions... ...help!

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Scripting data and time functrions... ...help!

    My latest journey into the "underbelly" of the linux beast!

    The Platform: I administer a system that creates a continous log file of events. This is a Red Hat RHEL 4 Update 5 system (circa 2007). It exists on a stand alone network that does not have internet access.

    The Task:
    My boss has tasked me with the first business day of every month, to make a copy of the log file onto my thumb drive, rename it, and upload it to the company server.

    The Complications: The order of the day requires the log file to be collected exactly on the first business day of the month. The file is root ownership and buried in a pile of subdirectories. The only way to get the file onto the internet and to my server is via a thumb drive. Thumb drives are not mounted when inserted nor is there any dialog to do so. The command line is used for virtually every task, with the exception of several Windows machines also on the network.

    The Goal: By using a Windows machine as the conduit, I can easily insert my thumb drive and drag and drop the file to it. I decided I could script a way to automagically copy and rename the log file and place it neatly on the Windows computer and do it on the first business day. That way, if I'm absent or otherwise occupied, I still have the file available of the desired time/date. All I have left to do in insert thumb drive, copy the newly renamed file to it, upload from my desktop to the server, done.

    So I needed to be able to detect the correct moment the file should be copied. I decided a cron job wouldn't work for two reasons: 1- the system may or may not be on at a particular hour of the day, 2- How do you tell crontab what the first business day of each month is?

    The system is turned on every business day, but maybe at 5am or maybe not until 10am. If it comes on a 5am, it might go into use immedately thus putting undesired data in the log, thus the copy must be made immediately following bootup before the system can be used and only on the first business day.

    Here's my idea: At boot up the log file is touched so the access date is reset. So at boot time, compare the current MONTH with the date stamp of the previously copied and renamed log on the Windows machine. If the month is the same - don't make a new copy of the log. If the month is different, make a new copy and overwrite the old one. Then the file on the Windows machine is always last months log uncorrupted by this months activities. Then I can copy and upload it in a more leisurely fashion.

    Here's my script entries I put in rc.local:
    Code:
    THISMONTH = date +%m
    LOGMONTH = ls -l --time-style=+%m <LOGFILE> | awk '$6 {print $6}'
    if [ $THISMONTH -ne $LOGMONTH ]
      then 
        cp <LOGFILE> <NEWLOGFILE>
    fi
    The functions seem to work as I want, but the darn thing writes a new logfile every bootup. It seems as though the IF isn't working for some reason.

    date +%m returns the current month numerically. Thus Sept. returns 09

    ls -l --time-style=+%m <LOGFILE> | awk '$6 {print $6}' extracts the numerical month from the file listing. So a file last accessed in Sept. returns 09

    So if 09 is not equal to 09, make a copy. Obviously, this is not true, so if IF should just exit, right? What am I missing? Anyone have a better idea on how the make this work?

    Please Read Me

    #2
    This is interesting.

    Never used AWK before, I hope you don't mind me posting.

    After looking up AWK, is it possible that the print part actually outputs 09 and then a blank line (output record separator - ORS)? If so, perhaps the two aren't matching because of the blank line in one and not the other?

    Try "printf" instead of "print".

    ^ if any of that is incredibly stupid, then sorry

    Feathers
    samhobbs.co.uk

    Comment


      #3
      If that's trying to be a Bourne or bash script, the syntax of the assignments would be
      Code:
       THISMONTH=`date +%m`
      No spaces around the = and ASCII backticks around the command (typing this in Tapatalk with SwiftKey, I'm not sure the above are indeed ASCII).
      The awk command doesn't look right; I suspect you want
      Code:
       awk '{print $6}'
      HTH,

      Regards, John Little
      Regards, John Little

      Comment


        #4
        Not at the subject machine right now, but regarding the awk part:

        awk '$6 {print $6}' returns 09 for a file created in Sept. So does awk '{print $6}' but the difference is if you apply the function to an entire directory, the first one produces a correct list of months of each file or directory within the target, the second produces a list with a blank line at the beginning (I suppose because it acts on . ?) so I stuck with the second choice.

        Feathers has an idea worth checking, so I ran this test on my server here:

        Code:
        smith@server:~$ date +%m
        09
        smith@server:~$ ls -l --time-style=+%m pkg.lst | awk '$6 {print $6}'
        10
        smith@server:~$
        so you can see no extra carriage returns. However, printf returns:
        Code:
        smith@server:~$ ls -l --time-style=+%m pkg.lst | awk '$6 {printf $6}'
        10smith@server:~$
        At this point, I'm still looking at the if...

        thanks for participating!

        Please Read Me

        Comment


          #5
          Further testing reveals jlittle may be on the money. I will edit in the morning and report...

          Please Read Me

          Comment


            #6
            awk '{print $6}' means print field 6 for every line of input, a typical use in scripts. awk '$6 {print $6}' means print field 6 if field 6 is "true", though some awks might complain, it's not normal awk. I think you intend your ls to give exactly 1 line of output, but maybe there may be none I suppose.

            Regards, John Little
            Regards, John Little

            Comment


              #7
              A couple of things for shell scripts. In order to get the output of a command in a variable, you need backquotes or $( ); No spaces surrounding "="; also, it is good form and less problematic if when testing variables in an if-statement if you surround them with double quotes instead of leaving them bare.

              This would be better:

              THISMONTH=$(date +%m)
              LOGMONTH=$(ls -l --time-style=+%m <LOGFILE> | awk '{print $6}')
              if [ "$THISMONTH" -ne "$LOGMONTH" ]

              ..

              Comment

              Working...
              X