Msys (или cygpath для msys?)
Мне нужно передать /DEF:c:\filepath\myLib.def "из командной строки из bash script в компилятор/компоновщик MS. Путь создается как часть процесса сборки с помощью bash script. В принципе, аргумент, который проходит мой script:
-DEF:/c/filepath/myLib.def
Преобразование пути
msys не может обрабатывать его должным образом, потому что оно не понимает часть /DEF:
. Он работает, если я делаю
-DEF=/c/filepath/myLib.def
но тогда инструменты ms не понимают этот параметр. Короче говоря, какой правильный способ записать этот параметр в MSYS bash, чтобы он преобразовал его в правильный аргумент?
В cygwin я могу использовать cygpath, но нет эквивалента, потому что кто-то из msys считает, что он не нужен (даже если есть скрипты для cygwin, который использует cygpath).
Ответы
Ответ 1
Обновление (август-2016):
Этот вопрос больше не уместен, поскольку msys2 теперь поставляется с cygpath
в своей установке.
...
Вкратце расскажу о моих исследованиях.
эквивалент cygpath в MSYS заключается в использовании этой команды:
{ cd /c/some/path && pwd -W; } | sed 's|/|\\|g'
Проблема с этим подходом заключается в том, что он требует существующего пути, например. c:\some\path
должен быть существующим каталогом; однако real 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
не существует на вашем ПК, он попытается преобразовать обратную косую черту и заменить /c/
на c:\
(или любую другую букву диска). Единственным недостатком этого является то, что он не будет корректно работать с несуществующими путями, которые содержат смонтированный компонент, например /bin/does-not-exist
или /usr/bin/does-not-exist
.
Еще один подход - использовать cygpath из cygwin в MSYS. Кажется, что 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
Ответ 2
Я использую это с помощью 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
}
Ответ 3
использовать pwd -W
или
скачать cygpath для msys здесь http://mingw.5.n7.nabble.com/enhanced-version-of-cygpath-td28556.html
и используйте cygpath -wa
Ответ 4
Как и 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/'
}
Ответ 5
Мой bash foo слаб, и я не мог получить регулярные выражения, работающие в bash 3.1, поэтому я взломал perl script для него:
#!/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);
Ответ 6
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 из преобразованного пути, f.e.
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, потому что
- автоматическое преобразование пути неадекватно
для f.e.
Ответ 7
Как насчет этого?
cmd //c echo <your path>
Он может работать не всегда, но это самый короткий найденный