web-dev-qa-db-fra.com

conversion du chemin d'accès msys (ou cygpath pour msys?)

Je dois passer l'option de ligne de commande "DEF:c:\filepath\myLib.def" d'un script bash au compilateur/lieur MS. Le chemin est généré dans le cadre du processus de construction par un script bash. passe est:

-DEF:/c/filepath/myLib.def

La conversion de chemin MSYS ne peut pas le gérer correctement car il ne comprend pas la partie /DEF:. Ça marche si je le fais 

-DEF=/c/filepath/myLib.def

mais alors les outils ms ne comprennent pas ce paramètre. En bref, quelle est la bonne façon d'écrire ce paramètre dans MSYS bash afin qu'il le convertisse en argument correct?

Sur cygwin, je pourrais utiliser cygpath, mais il n'y a pas d'équivalent, car quelqu'un de msys pense que ce n'est pas nécessaire (même s'il existe des scripts pour cygwin qui utilisent cygpath).

29
Pavel

Mise à jour (août 2016):

Cette question n'est plus pertinente, car msys2 est maintenant livré avec cygpath dans son installation.

...

Je vais résumer mes recherches ici.

Le cygpath équivalent dans MSYS est d'utiliser cette commande:

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

Le problème avec cette approche est qu’elle nécessite un chemin existant, par exemple. le c:\some\path doit être un répertoire existant; cependant, réel cygpath prend en charge les chemins qui n'existent pas.

Donc, si vous avez besoin d’obtenir un chemin vers un répertoire qui n’existe pas, vous pouvez alors utiliser la conversion sed du chemin:

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

La bouchée de slash est là pour satisfaire les règles de citations de sed. Donc, si c:\some\path n'existe pas sur votre PC, il essaiera de convertir les barres obliques inversées et remplacera /c/ par c:\ (ou toute autre lettre de lecteur). Le seul inconvénient est que cela ne fonctionnera pas correctement. Les chemins non existants contenant un composant monté, tel que /bin/does-not-exist ou /usr/bin/does-not-exist.

Une autre approche consiste à utiliser cygpath de cygwin dans MSYS. Il semble que cygwin définit la variable d'environnement global CYGPAT, c'est-à-dire que vous pouvez l'utiliser à partir de cmd.exe normal:

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

ou de MSYS:

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

aussi longtemps que vous définissez le point /c sur /cygdrive/c dans cygwin. Mais cette approche vous imprimera /usr situé dans l’installation de cygwin, pas dans MSYS.

En bref, je pense que msys devrait vraiment inclure le véritable cygpath dans l'ensemble d'outils par défaut uniquement dans certains cas qui ne sont pas gérés automatiquement par la logique de conversion des arguments de la ligne de commande msys

41
Pavel

Semblable à dmitri-rubinstein @ ci-dessus, j'ai un peu nettoyé le code et ajouté la conversion inversée.

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/'
}
7
TJR

utiliser pwd -W

ou téléchargez cygpath pour msys à partir d’ici http://mingw.5.n7.nabble.com/enhanced-version-of-cygpath-td28556.html

et utilisez cygpath -wa

6
Alex V.

J'utilise ceci avec 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
}
6
Dmitri Rubinstein

Mon bash foo est faible et je ne pouvais pas utiliser les regex fonctionnant dans bash 3.1, alors j'ai piraté un script Perl pour cela:

#!/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);
3
tanglebones

MSYS cygpath

Programme

Ce programme convertit un chemin DOS en un chemin UNIX et vice versa

#!/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);

Comparé à Cygwin cygpath

La sortie de ce programme est meilleure que celle de Cygwin cygpath dans MSYS car

  • Cygwin cygpath supprime la maison Cygwin d’un chemin converti, par exemple.
cygpath "$CYGWIN/usr/local/bin"
/usr/local/bin

ce qui pose problème car

  • il est parfois utile de convertir un chemin d'accès Cygwin DOS en un chemin UNIX dans le but de copier des fichiers de Cygwin vers MSYS

Ce programme ne supprime pas la maison Cygwin

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

Comparé à la conversion automatique du chemin MSYS

La conversion de chemin manuelle a une utilisation dans MSYS car

  • la conversion de chemin automatique est inadéquate

pour f.e.

2
John Peterson

Qu'en est-il de celui-ci? cmd //c echo <your path>

Cela ne fonctionne peut-être pas toujours mais c'est le plus court que j'ai trouvé

1