我需要从一个bash脚本到MS的编译器/链接器传递/DEF:c:\filepath\myLib.def”命令行选项。通过bash脚本作为生成过程的一部分产生的。基本上,参数中的路径,我的脚本通过为:
-DEF:/c/filepath/myLib.def
MSYS路径转换不能处理它正确,因为它不明白/DEF:
一部分。 它的工作原理,如果我做
-DEF=/c/filepath/myLib.def
但随后MS工具不了解这个参数。 总之,什么是写在MSYS的bash该参数,使其将其转换为正确的参数的正确方法?
在Cygwin我可以使用cygpath,但没有等同的,因为从MSYS有人认为,这是没有必要的(即使是使用cygpath Cygwin的脚本)。
更新(8 - 2016):
这个问题不再是相关的,因为msys2现在带有cygpath
在其安装。
...
我在这里总结一下我的研究。
该cygpath相当于MSYS是使用下面的命令:
{ 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-exist
或/usr/bin/does-not-exist
。
还有一个办法是在MSYS使用cygpath cygwin的版本。 看来,cygwin的设置全局环境变量CYGPATH,也就是说,你可以从常规的cmd.exe的使用方法:
%CYGPATH% -w /c/some/path
C:\some\path
或者从MSYS:
$CYGPATH -w /c/some/path
C:\some\path
只要你设置为指向/c
到/cygdrive/c
Cygwin中。 但是,这种方法将打印你/usr
位于Cygwin安装,而不是在MSYS。
总之,我觉得应该MSYS确实包括工具的默认设置真正cygpath只是某些情况下不是由MSYS命令行参数转换逻辑自动处理
使用pwd -W
或从这里下载cygpath的MSYS http://mingw.5.n7.nabble.com/enhanced-version-of-cygpath-td28556.html
并使用cygpath -wa
类似德米特里 - 鲁宾斯坦@上面,我清理了一下代码,并添加了反向转换为好。
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/'
}
我用这与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
}
我的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);
MSYS cygpath
程序
这个程序转换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
该程序的输出比从Cygwin的输出更好cygpath
在MSYS因为
- Cygwin的
cygpath
从转换的路径,铁删除Cygwin的家
cygpath "$CYGWIN/usr/local/bin"
/usr/local/bin
这是因为有问题
- 它有时有用到DOS Cygwin的路径转换为UNIX路径复制文件从Cygwin来MSYS的目的
这个程序不会删除Cygwin的家
cygpath "$CYGWIN/usr/local/bin"
/c/file/program/cygwin/usr/local/bin
相比自动MSYS路转换
手动路径转换在MSYS因为使用
对于FE
这个怎么样 ? cmd //c echo <your path>
它可能并不总是工作,但它是我发现的最短的