Windows Services for UNIX (SFU) includes
UNIX and Linux binaries that you can run
from a Windows command line or in a
batch file. Installing SFU is easy, and you get
a host of new commands that don’t exist in
Windows. When you combine the SFU commands
with the Windows For command,
you can create powerful tools.
I found this out firsthand recently. I
wanted to email myself the log file from
each nightly NTBackup job so I could check
it. Because the log files’ names are the dates
on which the backups ran, I knew that I
could use the command
Dir *.log /o:-d
in the C:\Documents and Settings\Administrator Local Settings\Application Data\Microsoft Windows NT\NTBackup\Data directory
to get a list of the log files’ pathnames, sorted
with the newest log file first. However, I needed
to extract the filename from the most
recent log file’s pathname. The Windows For
command can’t do that on its own. What I
needed was a command to read the Dir command’s
output, find the line containing the
current date, and extract the filename so that
the file could be emailed to me.
I initially thought of using the SFU grep
command to extract the filename. Like the
Windows Find command, the SFU grep
command finds lines in a text file containing
a specified string. However, there’s an
even better tool: the SFU find command.
You can use the SFU find command to find
files that meet certain criteria, then perform
operations on those files.
Using the SFU find command and the
Windows For command, I came up with the
command sequence
For /f "usebackq" %%T in
(`c:\SFU\common\find . -ctime 0
-name "*.log"`) Do Set fn=%%T
(Although the command appears on
several lines here, you’d enter it on one
line in a batch file.) Since you might not be
familiar with the SFU find command, let’s
walk through it. To use the SFU find command
from a Windows batch file, you first
need to call the command by specifying its
pathname. If you install SFU in the default
location, the SFU commands are in two
directories: C:\SFU\common and C:\SFU bin. The files in the common directory have
an .exe extension, whereas the files in the
bin directory don’t. For Windows, you use
the files in the common directory.
The SFU find command, which is case
sensitive like all the SFU commands, can
take up to three parameters. The first
parameter specifies the location to search.
In this case, I wanted to search the current
directory and its subdirectories, so I
specified a period. The second parameter
provides the criteria the files must meet to
be included in the result set. In my case, I
had two criteria:
• The files’ last modification date needed
to be the current date. I used the -ctime
option followed by a 0 to specify that
I wanted to find files in which the last
status change was 0 days ago.
• The files’ extensions had to be .log. I used
the -name option followed by “*.log”
to indicate that I wanted only log files.
The quotes are necessary to stop the
pre-expansion of the * wildcard by the
Windows command shell.
The SFU find command has an optional
third parameter, which you use to specify
the operation to perform on the files that
meet the criteria. In my case, I didn’t include this parameter. Note that there are many
parameters and options you can use with
the SFU find command. Unfortunately, this
command’s online documentation isn’t as
helpful as it could be, but you can find
a good overview of this command at
linuxmanpages.com/man1/find.1.php.
There are some items in the Windows
For command portion of the command
sequence that are worth pointing out. First,
note the use of the usebackq option with
the /f parameter. When you use this option,
the Windows command shell interprets any
text enclosed in back ticks (`) as commands
to execute, which in turn allows quotes
inside the command.
Also note the double percent signs (%%).
When you use an iterative variable (in this
case, %%T) in a Windows For command that
you execute in a batch file, you need to use
a double percent sign. The %%T variable
stores the filename that the SFU find command
returns. This filename is then set to
the fn variable. In the batch file I created, I
use Blat and the filename in the fn variable
to email the file to myself. (Blat is a free
command-line email program at www.blat.net.)
I also used the SFU find and Windows
For commands together to solve a similar
problem. I wanted to create a batch file that
not only sent daily database backup files
to an offsite ftp server for storage but also
emailed the results of this operation to me
so I’d know whether it was successful. To
email those daily results, I needed a command
to get the current date and extract
portions of that date. Using the SFU find
command and the Windows For command,
I came up with the command sequence
For /f "usebackq tokens=1,2,3" %%T
in (`c:\SFU\common\date
+"%%A %%m%%d %%d/%%m/%%Y"`)
Do Set dow=%%T & Set dom=%%U
& Set today=%%V
(Although the command appears on
several lines here, you’d enter it on one line
in a batch file.)
As you can see, this command sequence
uses the SFU date command. You can use
this command to obtain the current time
in a given format or set the system date. In
this case, I use it to obtain the current time.
The + sign after the command pathname
signals the start of a formatting string
that specifies the parts of the date to be
returned by the SFU date command and
how those parts should be formatted. Each
format option begins with a % sign (%% in
a batch file). If you specify two options with
no space between them, the Windows For
command treats the output from the two
options as one string. If you separate the
two options with a space, the Windows For
command treats the output from each option
as a separate string, which enables you
to assign them to separate variables. In this
case, the SFU date command returns three
separate strings:
• The %%A option tells SFU to return the
full weekday name (e.g., Sunday). The
Windows For command assigns this
string to the dow variable.
• The %%m%%d option tells SFU to return
the month and day of the month in the
format mmdd. This string is assigned to
the dom variable.
• The %%d/%%m/%%Y option tells SFU to
return full date in the British format dd/
mm/yyyy. This string is assigned to the
today variable.
These format options are only a few of the
many options available. You can see all the
options by typing
date -help
in SFU.
In the Windows For command portion
of the command sequence, note the
tokens=1,2,3 option with the /f parameter.
This option tells the Windows command
processor to retrieve the first three strings
(i.e., tokens) returned by the SFU date command.
The command processor assumes
you’re using a space or tab as the delimiter.
If you want to use another character (e.g., a
comma) as a delimiter, you need to include
the delims= option with the /f parameter.
The batch file in which I used the second
command sequence contains another
example of how to use the SFU find and
Windows For commands together. You can
download that batch file by clicking
the Download the Code Here button.
I hope these examples give you food for
thought about using SFU commands with
Windows commands. You can download
SFU at technet.microsoft.com/en-us/interopmigration/bb380242.aspx. (You
can also get the UNIX and Linux binaries
at Cygwin—www.cygwin.com.) Before
you install SFU, you need to create two
files—passwd and group—and place them
in the \%SystemRoot%\System32\drivers etc folder. You don’t need to populate
these files because you aren’t fully using
SFU; you’re using only the UNIX and Linux
binaries. For more information on how to
install SFU, see the Windows Services for
UNIX web page at technet.microsoft.com/en-us/interopmigration/bb380242.aspx.
End of Article