преобразование пути msys (или cygpath для msys?)

Мне нужно передать параметр командной строки /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 считает, что он не нужен (даже если есть скрипты для cygwin, которые используют cygpath).


person Pavel P    schedule 18.08.2012    source источник
comment
Ненужный аргумент можно растянуть очень далеко. Но иногда это полезно, например, со сценарием оболочки Jython, допускающим Cygwin, но не MSYS. Сценарий оболочки Jython вызывает cygpath. Если мы добавим cygpath.exe из ответа @ user1307996 в корзину MSYS, это сработает.   -  person Evgeni Sergeev    schedule 25.12.2013
comment
Здесь обрабатываются оба направления: stackoverflow.com/q/13701218/321973   -  person Tobias Kienzler    schedule 07.01.2015
comment
@TobiasKienzler Попробуйте преобразовать \Windows в posix с помощью этих сложных скриптов. Нет смысла не использовать cygpath на cygwin   -  person Pavel P    schedule 07.01.2015
comment
конечно, нет, если только у вас нет cygpath в наличии ...   -  person Tobias Kienzler    schedule 07.01.2015
comment
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что описанная проблема была решена в более поздней версии программного обеспечения - msys2 включает cygpath.   -  person Richard Neish    schedule 21.02.2019


Ответы (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 не существует на вашем компьютере, он попытается преобразовать прямую косую черту в обратную и заменить /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.

person Pavel P    schedule 21.08.2012
comment
Нет необходимости избегать обратной косой черты, если вы уже используете одинарные кавычки. - person Rufflewind; 01.03.2015
comment
Отличный ответ, однако, если ваш сценарий sed изменен для изменения ([a-z]) на ([a-z, A-Z]), тогда также могут использоваться заглавные буквы дисков. - person stellarpower; 25.09.2015
comment
Кроме того, удалив косые черты forwars в конце первого сценария sed, можно преобразовать что-то вроде / c в C: вместо \ c. - person stellarpower; 26.09.2015
comment
@stellarpower Но тогда /abc также будет преобразован в a:bc или a:\bc в зависимости от того, во что /a преобразовано. - person Pavel P; 14.04.2017
comment
Часть sed неточна - pwd -W генерирует заглавную букву диска, тогда как sed сохраняет строчную (да, иногда это имеет значение). - person yugr; 12.01.2020

используйте 1_

или загрузите cygpath для msys отсюда http://mingw.5.n7.nabble.com/enhanced-version-of-cygpath-td28556.html

и используйте cygpath -wa

person Alex V.    schedule 28.08.2013
comment
Чем он отличается от моего собственного ответа? - person Pavel P; 02.09.2013
comment
ссылка, которую я предоставил, указывает на cygpath.exe, который, вероятно, отличается от cygwin. - person Alex V.; 03.09.2013
comment
Приведенная ссылка предоставляет cygpath, который не работает должным образом. Например. cygpath -w /c/foobar печатает c:/foobar, а должен печатать c:\foobar. - person Dan Jones; 25.03.2015

Как и в случае с 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/'
}
person TJR    schedule 01.10.2014

Я использую это с 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
}
person Dmitri Rubinstein    schedule 15.03.2013

Мой 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);
person tanglebones    schedule 21.08.2012
comment
Я знаю, как это сделать с помощью скриптов; Я думаю, что есть какой-то специфический для MSYS способ цитировать аргументы, чтобы он автоматически преобразовывал этот путь. Это то, что я ищу. - person Pavel P; 22.08.2012

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, потому что

  • автоматическое преобразование пути неадекватно

для f.e.

person John Peterson    schedule 13.07.2013

Как насчет этого ? cmd //c echo <your path>

Это может работать не всегда, но это самое короткое, что я нашел

person Candide Guevara Marino    schedule 19.11.2015
comment
Решение, основанное на том, как передать его из Makefile, предоставляется в stackoverflow.com/questions/40257679/ - person Klamer Schutte; 26.10.2016

Это работает для меня

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

ref

person Steven Penny    schedule 30.01.2013
comment
Вы пробовали мое собственное решение: sh -c 'cd /c/some/path; pwd -W'? он функционально эквивалентен cygpath -w '/c/some/path' на cygwin. Возможно, ваше решение имеет такую ​​функциональность, как cygpath, но не очень ясно, как преобразовать ее в команду, подобную cygpath. - person Pavel P; 31.01.2013