path portability mingw32 msys cygpath

Conversión de ruta de msys(o cygpath para msys?)



portability mingw32 (7)

MSYS cygpath

Programa

Este programa convierte una ruta de DOS a una ruta de UNIX y viceversa

#!/bin/env perl # DOS to UNIX path conversion # © John S. Peterson. License GNU GPL 3. use strict; use Getopt::Std; # usage if ($#ARGV == -1) { print ''Usage: cygpath (-w) NAME... Convert Unix and Windows format paths Output type options: -w, --windows print Windows form of NAMEs (C:/WINNT) ''; exit 0; } # option my %opt; getopts(''w'', /%opt); # convert path my @r; foreach my $e (@ARGV) { if ($opt{w}) { # add drive letter suffix $e =~ s,^//([A-Za-z])//,/1://,; $e =~ s,//,//,g; } else { $e =~ s,//,//,g; # add leading slash $e = "/$e"; # remove drive letter suffix $e =~ s,:,,; } push @r, $e; } print join("/n", @r);

En comparación con Cygwin cygpath

La salida de este programa es mejor que la salida de cygpath Cygwin en MSYS porque

  • Cygwin cygpath elimina el inicio de Cygwin de una ruta convertida, fe

cygpath "$CYGWIN/usr/local/bin" /usr/local/bin

lo cual es un problema porque

  • a veces es útil convertir una ruta Cygwin de DOS a una ruta UNIX con el fin de copiar archivos de Cygwin a MSYS

Este programa no elimina el hogar de Cygwin.

cygpath "$CYGWIN/usr/local/bin" /c/file/program/cygwin/usr/local/bin

Comparado con la conversión automática de rutas de MSYS

La conversión de ruta manual tiene un uso en MSYS porque

  • La conversión automática del camino es inadecuada.

para fe

Necesito pasar la opción de línea de comando /DEF:c:/filepath/myLib.def "de un script bash al compilador / vinculador MS. La ruta se genera como parte del proceso de compilación por un script bash. pasa es

-DEF:/c/filepath/myLib.def

La conversión de ruta de MSYS no puede manejarlo correctamente porque no entiende /DEF: parte. Funciona si lo hago

-DEF=/c/filepath/myLib.def

pero luego las herramientas ms no entienden este parámetro. En resumen, ¿cuál es la forma correcta de escribir ese parámetro en MSYS bash para que lo convierta en un argumento adecuado?

En cygwin podría usar cygpath, pero no hay equivalente, porque alguien de msys cree que no es necesario (incluso si hay scripts para cygwin que usan cygpath).


Al igual que dmitri-rubinstein @ anterior, he limpiado un poco el código y también he agregado la conversión inversa.

winpath() { if [ ${#} -eq 0 ]; then : skip elif [ -f "$1" ]; then local dirname=$(dirname "$1") local basename=$(basename "$1") echo "$(cd "$dirname" && pwd -W)/$basename" / | sed / -e ''s|/|//|g''; elif [ -d "$1" ]; then echo "$(cd "$1" && pwd -W)" / | sed / -e ''s|/|//|g''; else echo "$1" / | sed / -e ''s|^//(./)/|/1://|g'' / -e ''s|/|//|g'' fi } unixpath() { echo "$1" / | sed -r / -e ''s///////g'' / -e ''s/^([^:]+):////1/'' }


Estoy usando esto con msysgit:

winpath() { if [ -z "$1" ]; then echo "$@" else if [ -f "$1" ]; then local dir=$(dirname "$1") local fn=$(basename "$1") echo "$(cd "$dir"; echo "$(pwd -W)/$fn")" | sed ''s|/|//|g''; else if [ -d "$1" ]; then echo "$(cd "$1"; pwd -W)" | sed ''s|/|//|g''; else echo "$1" | sed ''s|^//(./)/|/1://|g; s|/|//|g''; fi fi fi }


Mi bash foo es débil y no pude hacer que las expresiones regulares funcionen en bash 3.1, así que hackeé un script en perl para ello:

#!/bin/env perl use strict; my @r; foreach my $e (@ARGV) { $e=~s///////g; $e=~s/^//([A-Za-z])////1:///; push @r, $e; } print join(" ", @r);


Que tal este ? cmd //c echo <your path>

Puede que no funcione siempre, pero es lo más corto que encontré.



Actualización (agosto-2016):

Esta pregunta ya no es relevante, ya que msys2 ahora viene con cygpath en su instalación.

...

Voy a resumir mi investigación aquí.

El equivalente de cygpath en MSYS es usar este comando:

{ cd /c/some/path && pwd -W; } | sed ''s|/|//|g''

El problema con este enfoque es que requiere una ruta existente, por ejemplo, la ruta c:/some/path tiene que ser un directorio existente; sin embargo, cygpath real admite rutas que no existen.

Por lo tanto, si necesita obtener una ruta a un directorio que no existe, puede cambiar a la conversión sed de la ruta:

{ cd 2>/dev/null /c/some/path && pwd -W || echo /c/some/path | sed ''s|^//([a-z,A-Z]/)/|/1:/|''; } | sed ''s|/|//|g''

El bocado de barras está ahí para satisfacer las reglas de sed de sed . Por lo tanto, si c:/some/path no existe en su PC, intentará convertir barras diagonales hacia atrás y reemplazar /c/ con c:/ (o cualquier otra letra de unidad). El único inconveniente de esto es que no funcionará correctamente las rutas no existentes que contienen un componente montado, como /bin/does-not-exist o /usr/bin/does-not-exist .

Un enfoque más es usar cygpath de cygwin en MSYS. Parece que cygwin establece la variable de entorno global CYGPATH, es decir, puede usarla desde cmd.exe normal:

%CYGPATH% -w /c/some/path C:/some/path

o desde MSYS:

$CYGPATH -w /c/some/path C:/some/path

siempre que establezca apuntar /c a /cygdrive/c en cygwin. Pero este enfoque le imprimirá a usted /usr ubicado en la instalación de cygwin, no en MSYS.

En resumen, creo que msys debería incluir cygpath real en el conjunto predeterminado de herramientas solo para algunos casos que no son manejados automáticamente por la lógica de conversión de argumentos de la línea de comandos de msys.