Making Cygwin and Windows cooperate

Cygwin uses a different path scheme than Windows. If you use a Cygwin shell with Cygwin programs, then everything works well. But if you use a Cygwin shell as your default shell (which I do, because face it, cmd.exe sucks) and you’re running non-Cygwin programs, you can run into trouble because the shell may send Cygwin-style paths for filenames to Windows programs that don’t understand them.

For instance today I was using a Cygwin bash shell with a non-Cygwin Perforce client (i.e.: “p4″).

$ p4 open foo.cpp
Path '/cygdrive/c/dev/project/...\foo.cpp' is not under
client's root 'C:\dev\project'.

p4 is a regular (non-Cygwin) program and thus it doesn’t understand the Cygwin path that gets sent to it.

One way to fix this would be to find a version of p4 that was compiled against Cygwin.

Another way is to use the cygpath command to convert the Cygwin path to a Windows path.

$ p4 open $(cygpath -aw foo.cpp)
//depot/project/foo.cpp#2 - currently opened for edit

The -a option tells it to generate an absolute path and the -w option tells it to convert from a Cygwin path to a Windows path.

7 comments to Making Cygwin and Windows cooperate

  • I’ve used Cygwin/Windows daily now for several years, and have some helper scripts and aliases to help to translate paths for Windows applications.

    One common function is to translate a set of paths, as you describe above:

    for ((at=1; at <= $#; at++))
    do
        p="$p `cygpath -wa ${!at}`"
    done
    /cygdrive/c/Program\ Files/e/e.exe $p
    

    While not generic, it works well from the Cygwin/Bash shell. The above snip fails gracefully too, as cygpath ignores what it can’t translate. It’s also worth automating adding the Program\ Files path to your path (and its sub directories).

    FWIW, I’ve also found “Console2″ to be a good Cmd.exe replacement (I think it actually wraps it somehow with anti-aliasing). Console2 is like gnome-terminal, less a few awkward key and mouse bindings, and can be used with the Cygwin/bash terminal. It’s the only replacement so far that works with all of my scripts, tools, and such (including reasonable termcap support).

  • Oh, I should mention that I’ve found the “E editor” to be quite handy too (though a bit buggy still). It’s a Textmate clone for Windows, and it includes a Cygwin installation. I am looking forward to getting my teams to use it, as it makes the pain of Cygwin easier for most of the Window-ish devs.

  • It’s nice to find others sharing tips for integrating Cygwin with other, non-Cygwin apps. I posted a similar tip earlier this year, for launching Textpad from Cygwin.

    Unfortunately, my bash function only supported passing one filename on the command-line (a limitation I openly admitted at the time, and blamed on sheer laziness).

    Now, using Bruce’s for loop (comment #1), I’ve changed my function to handle converting multiple Cygwin-style paths into the Windows-style paths that Textpad needs.

    Thanks, guys!

  • I should note that there is a Cygwin version of p4, which I found at this page, which coincidentally has the same tip as me.

    You can copy the Cygwin p4.exe into C:cygwinbin and then use that, but it’s totally seamless, because if you were using the non-Cygwin P4, then your workspaces probably have Windows style paths in them and p4 will complain that your Cygwin paths do not reside in your workspace (the “is not under client’s root” error).

  • Jonathan

    The first solution requires far too much typing to use on a regular basis for a lazy programmer like myself. An extra “$(cygpath -wa path)” is too much.

    And looping through all the arguments won’t work either because some arguments are commands, others are switches. Also when setting up a remote machine, I want to make it work with minimum hassle.

    I think the simplest solution is to add the following to your .bashrc (sorry, I’m not sure how to make it fixed-font):

    function p4() {
    export PWD=`cygpath -wa .`
    /cygdrive/c/Program\ Files/Perforce/p4.exe $@
    }

  • yanos

    It’s better to quote the arguments:

    function p4() {
    export PWD=`cygpath -wa .`
    /cygdrive/c/Program\ Files/Perforce/p4.exe “$@”
    }

    That way it will also works with file with spaces in it.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>