41

我需要将 /DEF:c:\filepath\myLib.def" 命令行选项从 bash 脚本传递给 MS 编译器/链接器。路径是由 bash 脚本作为构建过程的一部分生成的。基本上,我的脚本的参数通行证是:

-DEF:/c/filepath/myLib.def

MSYS 路径转换无法正确处理它,因为它不理解/DEF:部分。如果我这样做,它会起作用

-DEF=/c/filepath/myLib.def

但是后来ms工具不理解这个参数。简而言之,在 MSYS bash 中编写该参数以便将其转换为正确参数的正确方法是什么?

在 cygwin 上我可以使用 cygpath,但没有等效的,因为来自 msys 的人认为不需要它(即使有使用 cygpath 的 cygwin 脚本)。

4

8 回答 8

56

更新(2016 年 8 月):

这个问题不再相关,因为msys2cygpath现在在其安装中附带。

...

我将在这里总结我的研究。

MSYS 中的cygpath等效项是使用以下命令:

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

这种方法的问题在于它需要现有路径,例如c:\some\path必须是现有目录;然而,真正的cygpath支持不存在的路径。

因此,如果您需要获取不存在的目录的路径,则可以回退到路径的 sed 转换:

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

满口的斜线是为了满足sed. 因此,如果c:\some\path您的 PC 上不存在,它将尝试将正斜杠转换为反斜杠并替换/c/c:\(或任何其他驱动器号)。唯一的缺点是它不能正常工作包含已安装组件的不存在路径,例如/bin/does-not-existor /usr/bin/does-not-exist

另一种方法是在 MSYS 中使用来自 cygwin 的cygpath 。似乎cygwin设置了全局环境变量CYGPATH,也就是说,你可以从常规的cmd.exe中使用它:

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

或来自 MSYS:

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

只要你在cygwin中设置指向/c即可。/cygdrive/c但是这种方法会将您打印/usr在 cygwin 安装中,而不是在 MSYS 中。

简而言之,我认为 msys 真的应该在默认工具集中包含真正的 cygpath,仅适用于 msys 命令行参数转换逻辑无法自动处理的某些情况

于 2012-08-21T21:57:23.423 回答
14

利用pwd -W

或从这里下载 msys 的 cygpath http://mingw.5.n7.nabble.com/enhanced-version-of-cygpath-td28556.html

并使用cygpath -wa

于 2013-08-28T12:36:08.820 回答
8

与上面的 dmitri-rubinstein@ 类似,我稍微清理了代码并添加了反向转换。

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/'
}
于 2014-10-01T04:36:26.570 回答
6

我将它与 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
}
于 2013-03-15T14:10:54.330 回答
3

MSYScygpath

程序

该程序将 DOS 路径转换为 ​​UNIX 路径,反之亦然

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

与 Cygwin 相比cygpath

该程序的输出优于cygpathMSYS 中 Cygwin 的输出,因为

  • Cygwincygpath从转换后的路径中删除 Cygwin 主页,fe
cygpath "$CYGWIN/usr/local/bin"
/usr/local/bin

这是一个问题,因为

  • 为了将文件从 Cygwin 复制到 MSYS,有时将 DOS Cygwin 路径转换为 ​​UNIX 路径很有用

该程序不会删除 Cygwin 主页

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

与自动 MSYS 路径转换相比

手动路径转换在 MSYS 中很有用,因为

  • 自动路径转换不足

为铁

于 2013-07-13T19:28:59.823 回答
3

我的 bash foo 很弱,我无法让正则表达式在 bash 3.1 中工作,所以我为它破解了一个 perl 脚本:

#!/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);
于 2012-08-21T19:22:09.520 回答
3

这个怎么样 ? cmd //c echo <your path>

它可能并不总是有效,但它是我发现的最短的

于 2015-11-19T13:49:09.310 回答
0

这对我有用

df "$1" | tac >k
read b <k
rm k
set "$1" $b
echo ${1/$7/$2/}

参考

于 2013-01-30T08:11:23.173 回答