Cygwin paths and perlbrew
I've been messing around with perlbrew lately and decided to give it a whirl on Cygwin. Right off the bat I ran into a problem with my $PATH.
PATH=/usr/local/bin:/usr/bin:/usr/local/bin:/usr/bin:/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live:/cygdrive/c/Program Files (x86)/Common Files/Microsoft Shared/Windows Live:/cygdrive/c/Program Files (x86)/AMD APP/bin/x86_64:/cygdrive/c/Program Files (x86)/AMD APP/bin/x86:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program Files/Intel/WiFi/bin:/cygdrive/c/Program Files/Common Files/Intel/WirelessCommon:/cygdrive/c/Program Files (x86)/ATI Technologies/ATI.ACE/Core-Static:/cygdrive/c/Program Files (x86)/Intel/Services/IPT:/cygdrive/c/Program Files (x86)/Symantec/VIP Access Client:/cygdrive/c/Program Files (x86)/Sony/VAIO Startup Setting Tool:/cygdrive/c/Program Files (x86)/Common Files/Roxio Shared/10.0/DLLShared:/cygdrive/c/Program Files (x86)/Common Files/Roxio Shared/DLLShared:/cygdrive/c/Program Files (x86)/Windows Live/Shared
Spaces everywhere, which the perl installer did not take kindly to.
I had two options at this point:
Set $PATH to only include what was needed to install and be done with it
Spend a good chunk of time Googling how to convert the paths to something perl wouldn't complain about.
I of course, took option 2.
I wanted my default paths to work with whatever I needed to do. $PATH is given to Cygwin by Windows, so I'd like to keep it that way for consistency. The necessity of doing this can be debated.
/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live
/cygdrive/c/PROGRA~1/COMMON~1/MICROS~1/WINDOW~1
I found cygpath and thought it would be all I needed.
The command has options to display unix style paths, windows style paths and short paths, but it does not allow you to combine the short style with the unix style.
/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live
$ cygpath -m "/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live" C:/Program Files/Common Files/Microsoft Shared/Windows Live
$ cygpath -m -s "/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live" C:/PROGRA~1/COMMON~1/MICROS~1/WINDOW~1
I would need to create a shell script to combine the mixed and short style paths into something I could use.
# First we need to split $PATH # on ':' and put each line into # an array OLD_IFS=$IFS IFS=$'\n' paths=(`echo $PATH | tr -s ":" "\n"`) IFS=$OLD_IFS # The paths supplied from Windows # may not actually exist. These # paths will cause cygpath to error # so we will skip them and only # process actual directories. valid_paths=(); for path in "${paths[@]}"; do if [ -d "${path}" ]; then # Save the cygdrive we are parsing cygdrive_save=$(echo $path | grep -oEi "/cygdrive/[a-z]+") if [[ $cygdrive_save ]]; then # Get the short version of the path from cygpath # We can't have ':' in our path so only grab the # path following C: (or other drive letter) no_space_path=$(cygpath -a -m -s "${path}" | cut -d : -f 2); # Use the saved cygdrive from above and # prepend it to the short path valid_paths=("${valid_paths[@]}" "${cygdrive_save}${no_space_path}") else valid_paths=("${valid_paths[@]}" $path) fi fi done # Join the valid_paths array with ':' # and set $PATH OLD_IFS=$IFS IFS=":" PATH="${valid_paths[*]}" IFS=$OLD_IFS
Add to .bash_profile and now my $PATH looks like this:
$ printenv PATH /home/Kevin/perl5/perlbrew/bin:/usr/local/bin:/usr/bin:/usr/local/bin:/usr/bin:/cygdrive/c/PROGRA~1/COMMON~1/MICROS~1/WINDOW~1:/cygdrive/c/PROGRA~2/COMMON~1/MICROS~1/WINDOW~1:/cygdrive/c/PROGRA~2/AMDAPP~1/bin/x86_64:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WINDOW~1/v1.0:/cygdrive/c/PROGRA~1/Intel/WiFi/bin:/cygdrive/c/PROGRA~1/COMMON~1/Intel/WIRELE~1:/cygdrive/c/PROGRA~2/ATITEC~1/ATI.ACE/CORE-S~1:/cygdrive/c/PROGRA~2/Intel/Services/IPT:/cygdrive/c/PROGRA~2/Symantec/VIPACC~1:/cygdrive/c/PROGRA~2/Sony/VAIOST~1:/cygdrive/c/PROGRA~2/COMMON~1/ROXIOS~1/10.0/DLLSHA~1:/cygdrive/c/PROGRA~2/COMMON~1/ROXIOS~1/DLLSHA~1:/cygdrive/c/PROGRA~2/WIC4A1~1/Shared
Now the Perl install (and anything else that is space sensitive) works:
$ perlbrew list perl-5.14.2 $ perlbrew exec perl -v perl-5.14.2 ========== This is perl 5, version 14, subversion 2 (v5.14.2) built for cygwin-thread-multi-64int Copyright 1987-2011, Larry Wall Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5 source kit. Complete documentation for Perl, including FAQ lists, should be found on this system using "man perl" or "perldoc perl". If you have access to the Internet, point your browser at http://www.perl.org/, the Perl Home Page.
Shell scripting is not my strong suit. I'm guessing there is a better and possibly more efficient solution to this problem. I welcome any suggestions to clean it up.