webentwicklung-frage-antwort-db.com.de

msys pfad umwandlung (oder cygpath für msys?)

Ich muss die Befehlszeilenoption /DEF:c:\filepath\myLib.def "von einem Bash-Skript an den MS-Compiler/Linker übergeben. Der Pfad wird als Teil des Build-Prozesses von einem Bash-Skript generiert. Im Wesentlichen das Argument, das mein Skript ist Pässe ist:

-DEF:/c/filepath/myLib.def

MSYS-Pfadkonvertierung kann nicht richtig damit umgehen, da /DEF:-Part nicht verstanden wird. Es funktioniert, wenn ich es tue 

-DEF=/c/filepath/myLib.def

die ms-Tools verstehen diesen Parameter jedoch nicht. Kurz gesagt, wie schreibt man diesen Parameter in der MSYS-Bash so, dass er in das richtige Argument konvertiert wird?

Auf cygwin könnte ich cygpath verwenden, aber es gibt keine Entsprechung, da jemand von msys denkt, dass es nicht benötigt wird (selbst wenn es Skripts für cygwin gibt, die cygpath verwenden).

29
Pavel

Update (Aug-2016):

Diese Frage ist nicht mehr relevant, da msys2 jetzt in der Installation cygpath ist.

...

Ich werde meine Forschung hier zusammenfassen.

Das cygpath Äquivalent in MSYS ist die Verwendung dieses Befehls:

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

Das Problem bei diesem Ansatz ist, dass ein vorhandener Pfad erforderlich ist, z. Der c:\some\path muss ein vorhandenes Verzeichnis sein. aber echt cygpath unterstützt Pfade, die nicht vorhanden sind.

Wenn Sie also den Pfad zu einem Verzeichnis benötigen, das nicht existiert, können Sie auf die Konvertierung des Pfads zurückgreifen:

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

Der Schluck von Schrägstrichen erfüllt die Zitierregeln von sed. Wenn also c:\some\path nicht auf Ihrem PC vorhanden ist, wird versucht, Vorwärts-/Rückwärts-Schrägstriche zu konvertieren und /c/ durch c:\ (oder einen anderen Laufwerkbuchstaben) zu ersetzen. Der einzige Nachteil ist, dass nicht vorhandene Pfade, die eine gemountete Komponente enthalten, wie /bin/does-not-exist oder /usr/bin/does-not-exist, nicht ordnungsgemäß funktionieren.

Ein weiterer Ansatz ist zu verwenden cygpath von cygwin in MSYS. Es scheint, dass cygwin die globale Umgebungsvariable CYGPATH setzt, das heißt, Sie können sie von der regulären cmd.exe verwenden:

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

oder von MSYS:

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

solange Sie festgelegt haben, dass /c auf /cygdrive/c in cygwin zeigt. Aber bei diesem Ansatz werden Sie /usr in der cygwin-Installation und nicht in MSYS gedruckt.

Kurz gesagt, ich denke, msys sollte echten Cygpath in den Standard-Toolsatz einschließen, nur für einige Fälle, in denen die Befehlszeilenargument-Konvertierungslogik von msys nicht automatisch gehandhabt wird

41
Pavel

Ähnlich wie bei dmitri-rubinstein @ oben, habe ich den Code ein wenig aufgeräumt und auch die umgekehrte Konvertierung hinzugefügt.

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

verwenden Sie pwd -W

oder download cygpath für msys von hier http://mingw.5.n7.nabble.com/enhanced-version-of-cygpath-td28556.html

und benutze cygpath -wa

6
Alex V.

Ich verwende das mit msysgit:

winpath() {
    if [ -z "$1" ]; then
        echo "[email protected]"
    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

Mein bash-Foo ist schwach und ich konnte keine Regex in bash 3.1 zum Laufen bringen, also habe ich dafür ein Perl-Skript gehackt:

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

Programm

Dieses Programm konvertiert einen DOS-Pfad in einen UNIX-Pfad und umgekehrt

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

Im Vergleich zu Cygwin cygpath

Die Ausgabe dieses Programms ist besser als die Ausgabe von Cygwin cygpath in MSYS, weil

  • Cygwin cygpath entfernt das Cygwin-Home von einem konvertierten Pfad, z. B.
cygpath "$CYGWIN/usr/local/bin"
/usr/local/bin

was ist ein problem da

  • es ist manchmal nützlich, einen DOS-Cygwin-Pfad in einen UNIX-Pfad zu konvertieren, um Dateien von Cygwin nach MSYS zu kopieren

Dieses Programm entfernt das Cygwin-Zuhause nicht

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

Im Vergleich zur automatischen MSYS-Pfadkonvertierung

Manuelle Pfadkonvertierung wird in MSYS verwendet, weil

  • die automatische Pfadumwandlung ist unzureichend

für f.e.

2
John Peterson

Wie wäre es damit? cmd //c echo <your path>

Es funktioniert möglicherweise nicht immer, aber es ist das kürzeste, das ich gefunden habe