Using the date command in cygwin or Linux





Here was my problem:

I had a Microsoft SQL backup file named “filenamehere_backup_2012_04_13_00646736_7384937.bak” and instead of adjusting the backup file name I thought, can I work around it with a script?  In Windows there’s a “time” command.  If you type in “time /?” you’ll see it’s not exactly the most robust command for time data.  You can also use a command called “date” or “date /?” for the options there.  Again, not the most robust set of tools for playing with date data on the command line.  I’m sure there’s other M$ tools like VB scripting, etc but I’m not a VB guy so…moving on.

So how could I get the date option that’s variable and work with it better?  Cygwin!  Cygwin is  “a collection of tools which provide a Linux look and feel environment for Windows” (Ref the Cygwin Site).  So Cygwin allows you to run Linux binary files (exe’s) in Windows like a tool we’ll use to get our date that we need above “2012_04_13”.

Once you install Cywin (see other sites for that :P):

::  Put this script in a file called “daily.sh” or whatever.sh
::  Add it to your cron jobs “crontab -l” to list them, “crontab -e” to edit it and add your path + your .sh script to it.
::  Also note that you need to install “cron” in Cygwin, you have to look for it.  To use Nano as your default editor
::  You need to type into the cygwin command prompt”export EDITOR=nano”, so when you type “crontab -e” your default
::  editor will be nano which is far easier than vi (IMHO).
::  See crontab for more information should you need information on how to schedule scripts in crontab.  I have
::  some stuff about it here -> Link, where I talk about Zimbra backups if you need an idea.

daily.sh file contents:

#!/bin/sh

# Setting the current date variable
curtime=$(date +”%Y”_”%m”_”%d”)
# This yields: 2012_04_12 #For example, year, month, day
prevtime=$(date –date ‘-1 day’ +”%y”_”%m”_”%d”)
# Yields: Current date “2012_04_12” minus 1 day so result = “2012_04_11
# Also note that %y yields just “12” not “2012”

# Troubleshooting here… I like to “echo” the results before putting them into production so I know what I’ m going
# to get.  Simply delete the “#” if you want to run the line, the “#” is a comment, anything after it won’t run.
# echo Current date is
# echo $curtime
# echo File to move today is
# echo “filenamehere_backup_”$curtime”_*.bak”
# echo 1 day ago date is
# echo $prevtime
# echo FIle to delete today is
# echo “filenamehere_backup_”$prevtime”_*.bak”

# Production commands
cp /cygdrive/y/filenamehere_backup_”$curtime”_*.bak
/cygdrive/d/sql2daily
rm -f /cygdrive/d/sql2daily/filenamehere_backup_”$prevtime”_*.bak

Now what did we do in this script and what’s the point of using the date command?  I copied (cp) from the mapped “y:” drive which is a UNC path mapped drive to local disk d: where the tape backup looks to in the backups schedule (I added that folder specifically for this task).

“curtime” gives us the current date, like I’ve commented in my script above:  curtime=$(date +”%Y”_”%m”_”%d”)
# This yields: 2012_04_12 #For example, year, month, day.  If you type in the cygwin terminal (or a Linux terminal) “date –help” you’ll see a plethora of options, far more than in windows.

Next we have “prevtime=$(date –date ‘-1 day’ +”%y”_”%m”_”%d”)”, this takes the date and subtracts 1 day so the 12th becomes the 11th.  Note you can call it anything you want, I called them “curtime” and “prevtime” just because, you could call it peanut and butter if you wanted, they’re arbitrary.  Also note that if you want “10 days” simply change the ‘-1 day’ to ‘-10 days’ and it’ll kick it back 10 days.

* By the way, I notice the way my blog throws in the text that some stuff is a bit weird when you’re looking at it for example the “date – – date” on the published side looks like one dash “-” but there are actually two dashes “date dash dash date”.  So when you do a “date –date”…you need two dashes, there are two dashes there!

When I copy the current days backup into the folder by tomorrow it’s old and the script will copy the new days backup into the directory then “rm” or remove yesterdays copy so all I have in the folder is one days backup!  Lets say you wanted to keep 7 days worth of backups right?  Then you’d change the ‘-1 day’ to ‘-7 day’ or 30 days, etc, etc.  For me it’s the solution I was looking for IF your file has the date in the file name.  If it didn’t well then…you’ll need to do other stuff related to the “ls -la” command I’m sure and store your output into a file or a variable…I’d have to think about how you’d accomplish that BUT the “date” command worked wonderfully for what I needed it for!

* A bit of an edit to my post – I and others online have found it difficult to get cygwin and cron properly working on Windows, it seems to be hit or miss.  What I found and what’s working for me on Windows is bypassing cron by just calling your shell script from a batch file.  Here’s the code that worked for me:

c:
cd\
cygwin\bin\sh.exe -l /home/Administrator/daily.sh

The reason I have the “c:” in there is because I call the script from a D: drive and since cygwin is installed on c:\cygwin, if you don’t change drives in your bat file it doesn’t work ;)

 

Update:

If you’re on a Windows machine and you’re running a batch file that calls rsync or some other process via sh.exe and you encounter the error in your Schedules Task: 0x17

Check your folder permissions – it won’t run because you’re getting access denied on creating directories and files.  Run the script manually by double clicking on the batch file – you’ll see the error, you might have to put a “pause” statement in your batch file too so it won’t terminate.  I ran into this issue because the user account I was running the script under isn’t “administrator” – running your stuff as administrator probably isn’t a “best practice”…even though in practical terms there is no such thing (in my opinion).  I guess “best practice” is a discussion for another time :P