Showing posts with label perl. Show all posts
Showing posts with label perl. Show all posts

Jun 4, 2006

Using Perl with Cygwin

Some of us are using PERL on our Windows boxes to process data, etc. Many are also using cygwin to have a UNIX-like environment. This page offers some tips on getting ActiveState's PERL to work within a cygwin environment.

First, many folks recommend using a cygwin version of Perl if you are going to use cygwin as it avoids some of the problems I have addresed below. That may be a viable solution for you. I had already invested time in building my tools based on ActiveState (which has a richer set of add-ins, like modules). The cygwin folks also recommend getting a cygwin implementation of Xemacs.

The Problem

The problem basically boils down to the fact that cygwin attempts to offer a UNIX like file-system structure where absolute path names start with / instead of a windows style (e.g. c:). ActiveState's perl does not understand this UNIX style names. The very quick work around which I used for a long time was to always call perl scripts with absolute, windows-style path names (so cygwin does no conversion.) That is:

d:/parris/perl/stats.pl

works but

stats.pl

doesn't, even though d:/parris/perl is in the path. When you try to run a script relying on the #!c:/perl/bin/perl.exe syntax to specify the program that should process the script the shell (in this case cygwin's bash) effectively executes a command like:

c:/perl/bin/perl.exe absolute_script_name

If you are running from DOS everything is ok as this looks like:

c:/perl/bin/perl.exe d:/parris/perl/stats.pl

But with cygwin it looks like:

c:/perl/bin/perl.exe /cygdrive/d/parris/perl/stats.pl

and Perl balks with "no such file" because it can't resolve this pathname.

The Solution

To fix this problem, I use an intermediate shell script instead of the perl exectuable which takes the filename passed, converts it to a windows style pathname and then calls perl to process the script. The first line of my perl scripts looks like:

#!/usr/local/bin/perl

and /usr/local/bin/perl looks like:

#!/bin/sh

# This is necessary to make perl work with cygwin. Cygwin passes
# "cygwin style" paths to the program in the #! statement and ActiveState
# perl does not know what /cygwin/d/... means.

# So, we put #!/usr/local/bin/perl in the perl script and this is called
# This routine translates the path name to something of type d:/

args=""
while [ $# -gt 0 ]
do
var=$1
shift

if test "`echo $var | grep '/'`" = "$var"
then
# cygpath does the /cygwin/d/ to d:/ conversion
var=`cygpath -w $var`

# but then we have to swap \ for / (extra \ needed because the
# shell makes a first pass at removing the \.
var=`echo "$var" | sed 's/\\\/\\//g'`
fi
args="$args $var"

done
# finally the command is to call perl with the name of the script and the args.
cmd="c:/perl/bin/perl.exe $args"
$cmd

This uses the cygwin command, cygpath to convert to a windows style pathname and then convers \ to / before calling perl. This script could certainly be a lot more robust but it gets the job done for me.

** source

tags :