Logo

catlgrep

  • Archive
  • RSS
  • Ask me anything

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:

  1. Set $PATH to only include what was needed to install and be done with it
  2. 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.

I needed:

/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live

to become:

/cygdrive/c/PROGRA~1/COMMON~1/MICROS~1/WINDOW~1

cygpath

I found cygpath and thought it would be all I needed.

I was wrong.

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.

Unix Style Path:

/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live

Mixed Style Path:

$ cygpath -m "/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live"
C:/Program Files/Common Files/Microsoft Shared/Windows Live

Short Style Path:

$ cygpath -m -s "/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live"
C:/PROGRA~1/COMMON~1/MICROS~1/WINDOW~1

Fixing $PATH

I would need to create a shell script to combine the mixed and short style paths into something I could use.

Gist

# 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.

    • #perl
    • #perl5
    • #perlbrew
    • #cygwin
    • #cygpath
  • 1 year ago
  • 4
  • Comments
  • Permalink Permalink
  • Share

4 Notes/ Hide

  1. selbsil likes this
  2. catlgrep posted this

Recent comments

Blog comments powered by Disqus
← Previous • Next →

About

Author: Kevin McGrath

I've come to realize that I am terrible at 2 things:

  1. Keeping track of what I've done
  2. Contributing back to the coding community

This blog is an attempt to become better at both.

Twitter

loading tweets…

Following

  • RSS
  • Random
  • Archive
  • Ask me anything
  • Mobile

Effector Theme by Carlo Franco.

Powered by Tumblr