Как запустить внутреннюю команду cmd из оболочки msys?

Как запустить внутреннюю команду cmd из оболочки msys?

Утилита Windows CMDимеет ряд внутренних команд, таких как mklink. Как их можно использовать из msysоболочки ?

ОтCMDдокументация, /cпереключатель можно использовать для выполнения команды и выхода; но, похоже, это не работает.

  • Если я это сделаю, cmd /c mklinkкоманда mklinkне будет выполнена и CMDоболочка не закроется.

Перед нажатием Enter:

введите описание изображения здесь

После:

введите описание изображения здесь

Скриншот монитора процессов:

введите описание изображения здесь

  • Попытка запустить команду как фоновый процесс: cmd /c mklink &судя по всему работает - mklinkкоманда выполняется, но CMDоболочка не завершается. Каждый раз Enterпри нажатии CMDбудет становиться активной оболочкой.

решение1

  1. Найдите в %PATH% cmd.cmd или cmd.bat. Они могут конфликтовать с вашим cmd

  2. БегатьМонитор процессаи запустите ваш cmd /c mklink. Проверьте журнал ProcMon на предмет действительно выполненных команд.

решение2

У win7/cygwin/bash была та же проблема, решение — запустить cmd дважды и преобразовать слеши в обратные по мере необходимости в cmd (например): REPO_DIR=${REPO_DIR////\\} # Example, Turn c:/cvs into c:\cvs for cmd
cmd /C "cmd /C mklink /D .Repo $REPO_DIR" # launch cmd /C cmd /C cmd

решение3

Process Monitor помог отследить проблему. Это то, что msysпреобразуется /cв c:\; его нужно экранировать: cmd //c mklink. Объясняется, как выполняются эти преобразованияздесь. – Михай Ротару1 янв. '13 в 21:32

Я не смог заставить это работать, основываясь наКомментарий Михаяв одиночку, потому что путь все еще содержал прямые слеши /, и mklinkжаловался, что /msys64это недопустимый переключатель.

Поэтому я написал пакетный скрипт, чтобы это заработало.

Вот как я вызываю свой пакетный скрипт из MSYS:

 $ mingw_ln.bat "$destination" "$targetpath"

Пакетный скрипт берет эти два пути и преобразует их /в \, используя :OLD=NEWсинтаксис расширения параметров для замены строк. 1

set LINK=%1
set TARGET=%2

REM Convert POSIX paths to Windows paths
set LINK=%LINK:/=\%
set TARGET=%TARGET:/=\%

mklink /D %LINK% %TARGET%

1 Это похоже на синтаксис bash ${PARAM:/OLD/NEW}, для тех, кто с ним знаком

решение4

Развивая комментарий Михая Ротару:

Process Monitor помог отследить проблему. Это то, что msysпреобразуется /cв c:\; его нужно экранировать: cmd //c mklink. Объясняется, как выполняются эти преобразованияздесь. – Михай Ротару1 янв. '13 в 21:32

Это /cпреобразование c:\можно также избежать для некоторых или всех аргументов, используя переменную окружения MSYS2_ARG_CONV_EXCL.

Например

$ MSYS2_ARG_CONV_EXCL='*' /c/Windows/System32/cmd.exe /C "echo foo"

(Будьте осторожны, так как '*'и "*"будут означать разные вещи.)

Ссылаясь наMSYS2 документы:

MSYS2_ARG_CONV_EXCLможет *означать либо исключение всего, либо список из одного или нескольких префиксов аргументов, разделенных ;, например MSYS2_ARG_CONV_EXCL=--dir=;--bla=;/test [...]

Связанный контент