InterOpWindows Services For UNIX

Charlie Russel

If you're an administrator working in a mixed environment, Microsoft® Windows® Services for UNIX (SFU) 3.5 can make your life a lot easier. SFU provides a full-featured interoperability solution that includes a Network File Server (NFS) client, server and gateway for file system interoperability, and a Network Information Service (NIS). SFU also gives you User Name Mapping and password synchronization for identity management, along with the Interix subsystem.

In this article I'll focus on the Interix subsystem and utilities that make SFU an ideal interoperability environment for cross-platform scripting. When combined with the cross-platform file system client and server of SFU, and the versatile identity management features, you get the ideal toolset for managing and administering a diverse UNIX and Windows environment.

Interix Subsystem

The Interix subsystem is a full UNIX application and scripting environment. Unlike other interop products available from third-party vendors, the Interix subsystem is not just an emulation layer running on top of the Win32® subsystem, but a full subsystem of its own. As such, it enables higher performance and fewer compromises. Figure 1 depicts the Interix architecture.

Figure 1 Interix Architecture

Figure 1** Interix Architecture **

The Interix subsystem behaves just like any other UNIX machine and feels much more natural to the UNIX user or administrator. Applications can be ported to the Interix subsystem with relatively few changes, and the SDK includes more than 2000 UNIX APIs. The following sections explain what you must change and what will work without modification.

The Interix subsystem is fully case sensitive for both paths and filenames by default (as is UNIX), though case sensitivity can be disabled on Windows XP and Windows Server™ 2003. This does present some security issues that you'll need to understand. Specifically, under the Interix subsystem you can create multiple versions of a file with the same name, for example "temp1", "Temp1", and "TEMP1". When using the Interix subsystem, they will all appear to be different, as they should.

From the Win32 subsystem, applications will only see one of them. So, in the example of the three versions of temp1, only one can be edited with Notepad, and even if there is different content in the three files, only one of them will be accessible from the Win32 subsystem, and you can't easily predict which one that will be.

SFU implements a single rooted file system and all paths on the machine are relative to the Interix "/" (root) directory, which is equivalent to %SFUDIR% from the Windows shell. Drive letters are available via "/dev/fs/DRIVELETTER". This enables scripts and applications ported from UNIX and Linux to work more naturally, and with less conversion.

SFU treats slash ("/") and backslash ("\") characters exactly the same way as UNIX does. Scripts that must call Win32-based applications must protect backslash characters from being interpreted by the Interix shell. Pure UNIX scripts will have no problems, and should move to Interix without having to convert paths and parameters.

SFU and the Interix subsystem support both hard and symbolic links. The hard links are completely visible both from the Win32 subsystem and the Interix subsystem, but the symbolic links are only supported under the Interix subsystem.

UNIX and Linux users use a variety of different shells, from the Bourne shell (/bin/sh) to the Z shell, with just about everything in between. The relative merits of particular shells are the subject of rather heated debate, like you might find when discussing favorite sports teams. Interix ships with a Korn-compatible shell and a C shell, and others are available for download from InteropSystems (

The included Korn-like shell (/bin/ksh) is based on a publicly available Korn shell clone, and there is also a symbolic link to it from /bin/sh for those scripts that require a shell be at /bin/sh.

The included C shell is a somewhat outdated version of the Tenet C shell (/bin/tcsh). A symbolic link to it from /bin/csh provides compatibility for scripts that expect to find csh in /bin. Again, an updated version is available from InteropSystems.

Additional shells, including bash and zsh, are precompiled for SFU and available from InteropSystems. You can compile others using either the cc front end to Visual Studio®, or the gcc compiler available with SFU as an installation option.


SFU comes with more than 300 UNIX utilities as part of the Interix subsystem, with additional utilities available either from InteropSystems or by compiling from available source code. These utilities cover all the major UNIX utilities and areas—everything from addr to yacc—and behave exactly as you and your UNIX users would expect them to behave.

The utilities include familiar text processing tools, including grep, less, awk, sed, pr, and tr, batch processing tools such as at, cron, and batch, as well as job control tools like ps, nice, kill, and so on. They're all there and they work exactly as you would expect. Even the man command is just as ugly (but infinitely useful) as it's always been.

Utilities such as ps and kill work against both Interix and Win32 processes, making SFU particularly appealing for the system administrator. Need to find and kill all instances of a particular process? The script to do it in Interix is straightforward, whether the process is running in the Win32 subsystem or the Interix subsystem.

As a simplistic but useful example, suppose you have an unknown number of copies of a process running on a machine with SFU. Figure 2 shows a script that will kill them. This script would work exactly the same running on a UNIX or Linux system.

Figure 2 Kill Processes

#  Script to find all instances of a process and kill them
#    Takes a single argument, the process name to kill

script_name=${0##*/}    # save it off as a simple filename

# Check to see that we got exactly one argument
if [[ $# -ne 1 ]];
   print "usage: $script_name <process_name>"

# Count the number of instances of the process
let NUMPROC="$(ps -e | grep -i $PROCESS | grep -v grep | wc -l )"
print -n "Found $NUMPROC versions of $PROCESS, OK to kill them?(y|N) "
case $ANSWER in
   Y|y) ;;
     *) print "Exiting $script_name, failed to get confirmation of kill" 
        return ;;

# Now, to actually kill them...
let TRIES=0       # Must have a value assigned to the variable

while (( $NUMPROC > 0 )) && (( $TRIES <= 4 )); #Make sure we have a way out!
   # first, do the kill. 
   kill $(ps -e | grep -i $PROCESS | grep -v grep | tr -s " " | cut -c 1-5 ) 
   # Now, check to see if there are any left, and loop back if there are
   let "NUMPROC=$(ps -e | grep -i $PROCESS | grep -v grep | wc -l )"
   let "TRIES=$TRIES+1"
   print "This is try #$TRIES"


The Interix subsystem and SDK provide a full application development and migration environment, with more than 2000 UNIX APIs. Both XWindows and Curses-based applications are supported, along with a complete application execution environment that behaves exactly as UNIX applications expect. No special considerations for file locations or syntax are required. Symbolic links are fully supported, providing maximum location flexibility. SFU includes the GNU compilers, a version of Perl, and a cc front end to Visual Studio. Additional open source libraries, utilities, and compilers are available from InteropSystems. This makes it not only possible, but relatively easy, to port an existing UNIX application to run under Interix.


As you've noticed, scripts can easily be written that run transparently in SFU, UNIX, or Linux. When I ran the IT department of a software development company, we wrote all our scripts to create, support, and manage more than 60 instances of Oracle in a mixture of Korn shell and Perl. The scripts resided on a central NFS share that was accessible from any of our Windows, UNIX, or Linux servers, and we used them transparently against whatever Oracle instance we were working on, regardless of what platform it happened to be on. There were minor differences that were easily handled by doing what one should always do when writing robust and well-planned scripts: we had a central function library, used variables rather than hardcoded locations, and included solid error handling.

While enterprise-wide scripts are an important benefit of using SFU, there's also a place for quick, simple, one-off scripts for running simple jobs. The real benefit of SFU for those scripts is the much richer shell and utility environment. One task that was a never ending problem, especially for my database administrators, was knowing how much hard drive space they were consuming. Yes, they would be notified when they had gone too far, since we had procedures and scripts in place to automatically send a warning e-mail message to those who exceeded their allotments. But no one really wanted to get one of those e-mails, since their team lead got cc'd on them. So I created a simple little one-line script that they could run themselves whenever they wanted to know how much space they were using, especially in shared areas where several users might be storing files.

find . -user ${1:-$LOGNAME} -exec ls -oa {} \; | tr -s " " " " | \
   cut -f 4 -d " " | awk '{sum += $1 } END {print sum}'

This is a good example of how SFU makes life easier. It runs equally well in Windows or UNIX, and quickly tells the user how much space she (or someone else) is using. It's not particularly robust, doesn't have any error handling, and certainly isn't modular. But try doing the same thing from cmd.exe. Even after you'd done it, you'd still only have solved the Windows problem.


There are limitations to what you can do from the Interix subsystem. Because it is a completely separate subsystem, interprocess communication with applications in the Win32 subsystem is only available through pipes (which allow streaming of data between the two environments), memory-mapped files, sockets, and NTDLL-level semaphores. You can certainly call Win32-based applications and even batch files from an Interix subsystem application or script, but you'll have to do some testing to make sure that everything works as you expect, and you may have to deal with issues like protecting back slashes from evaluation by the Interix shell.

Scripts and applications that create or use files that then need to be accessible from the Win32 subsystem and regular Windows-based applications will need to be cautious about taking advantage of the Interix subsystem's full case sensitivity.

Device Files and Network Shares

SFU uses device files in the same way as UNIX or Linux, but you can't use the NFS file system as a bootable device for a diskless NFS workstation, and some common device files like /dev/tcp aren't possible. Windows drives are available as /dev/fs/DRIVELETTER—that is, /dev/fs/C, /dev/fs/D, and so forth. While you can create symlinks and/or aliases to mask this difference, it isn't recommended as a best practice. Windows network shares are available without mounting to a drive letter by using the convention /net/MACHINENAME/sharename. Shares that have been mounted on a drive letter are, of course, available as /dev/fs/DRIVELETTER.

Microsoft Windows Services for UNIX 3.5 provides all the features and tools necessary to give the user or administrator in a mixed environment the ability to use and manage their resources transparently across Windows, Linux, and UNIX systems.

Charlie Russel is a chemist by education, an electrician by trade, a Unix sysadmin and Oracle DBA because he raised his hand when he should have known better, an IT director and consultant by default, and a writer by choice. He is the author of more than a dozen books on operating systems and enterprise environments, and is a columnist for the Windows XP Expert Zone.

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.