Bash в Git для Windows: странность при запуске команды с CMD.exe/C с помощью args
Это скорее раздражение, чем проблема, но я бы очень хотел понять семантику здесь.
Все, что я хочу сделать, это запустить произвольную команду во временном сеансе командной строки, который сам запускается в сеансе bash.
Мой успех равен 50/50, так как некоторая команда работает так, как ожидалось, в то время как другие не так много.
Я думаю, что проблема может лежать вокруг аргументов, которые не выравниваются должным образом (т.е. отсутствующие или объединенные аргументы)
Я попытаюсь объяснить, что я имею в виду, странно, с помощью ряда команд и ответов. (Я пытаюсь, чтобы тестовое слово было напечатано на экране.)
Я запускаю их под GNU bash, версия 3.1.0 (1) -release (i686-pc-msys) В комплекте с Git -1.8.4:
Первая попытка:
$ cmd /c echo test
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
c:\>
Вторая попытка:
$ cmd '/c echo test'
test"
Третья попытка:
$ cmd "/c echo test"
test"
Четвертая попытка:
$ cmd /c\ echo\ test
test"
Пятая попытка:
$ cmd "/c echo" test
'echo" test' is not recognized as an internal or external command,
operable program or batch file.
Я бы очень признателен за любые указатели или понимание поведения, описанного выше, поскольку это неинтересно для меня и сводит меня с ума!
Edit:
Существует еще один вопрос, который похож на этот, но на самом деле это не так, главным образом потому, что он запускает пакетные файлы через CMD/C, который не требует никаких аргументов.
На самом деле он не отвечает на мой вопрос о том, как правильно предоставлять аргументы приложениям командной строки Windows, и хотя примеры относятся к CMD/C, ответ здесь может быть применен ко многим другим приложениям в командной строке Windows.
Ответы
Ответ 1
Это фактически задокументировано в файле ReleaseNotes (в папке верхнего уровня установленного вами Git для Windows)
Кроме того, необходимо уделить особое внимание прохождению Windows-программ в Windows-пути, поскольку они не имеют понятия о путях POSIX в стиле MSys. Вы можете использовать что-то вроде $(cmd//c echo "$ POSIXPATH" ).
Если вы используете cmd //c echo test
, он работает как ожидалось.
$ cmd //c echo test
test
Причина заключается в попытке убедиться, что пути posix в конечном итоге переданы в утилиты Git. По этой причине Git для Windows включает модифицированный уровень MSYS, который влияет на аргументы команды. Следует отметить, что оболочка bash и инструменты, поставляемые с Git для Windows, не используются в качестве универсальных инструментов Unix для Windows. Если вам нужен универсальный набор инструментов unix-стиля, вы должны установить MSYS или cygwin. Оболочка Git bash настроена для работы с Git, и иногда это показывает.
Ответ 2
После прочтения этой статьи я нашел решение, которое работает для меня:
$ cat gvim.sh
cmd << EOD
gvim [email protected]
EOD
$
Windows 8.1, Git (версия 1.9.5-preview20141217), GNU bash, версия 3.1.20 (4) -release (i686-pc-msys).
Ответ 3
Я могу в основном воспроизвести проблему, используя gnu bash для Windows.
Я не могу установить шаблон с первой формой без кавычек. Кажется, он работает с командой Windows ECHO, но не с другими командами, такими как DIR. EDIT. Получается, что gnu bash помещает кавычки вокруг моей команды, поэтому echo test
становится "echo" "test"
. Кавычки заставляют cmd.exe искать внешнюю команду вместо внутренней команды ECHO. У меня, похоже, есть "echo.exe", поэтому он работает. Странная вещь - цитаты вокруг теста не отображаются. Когда я пытаюсь запустить команду DIR, она терпит неудачу полностью, потому что не существует DIR.EXE.
Последующие формы с кавычками (кроме последнего) или экранированные пробелы работают так же, как вы видите - в команде есть нежелательная цитата.
Я не мог придумать чистого решения. Однако у меня есть уродливый хак, который должен дать вам желаемый результат. Просто конкатенируйте команду REM в конце вашей команды. REM прокомментирует нежелательную цитату. Важно, чтобы после REM было пробел, иначе REM"
не будет считаться допустимой командой. Любое из следующих действий должно работать.
$ cmd '/c echo test&rem '
$ cmd "/c echo test&rem "
$ cmd /c\ echo\ test\&rem\
Обратите внимание, что последняя команда имеет пробел после обратного слэша.
Этот метод должен работать практически для любой командной строки, которую вы можете выполнить с помощью CMD.EXE.
Ответ 4
Я заметил, что git - bash рассматривает аргумент /c
как диск C:
C:\Windows\system32\cmd.exe C:/ echo test
Как dbenham found добавлены двойные кавычки. Это echos test"
, например:
cmd /c\ echo\ test
Мне понадобилась одна и та же строка (script) для работы в git - bash, а также Cygwin Bash. Единственными способами, которые работают, являются
cmd /c\ echo\ test\&rem\
(обратите внимание, что эта строка должна заканчиваться пробелом) и
cmd << EOC
echo test
EOC
Так вывести каждое пространство после /c
и добавить \&rem\
в конец строки (включая конечное пространство), или просто оберните команду в здесь документе.
Все это, вероятно, зависит от версии git - bash и конкретных команд.: - (
Ответ 5
Это похоже на работу с 1.9.5.msysgit.1
!foo=`bar`
cmd //c \\\\unc-path\\with\\slashes -args \"Quoted Arguments $foo\"
Ответ 6
Поскольку вы упоминаете, что используете пакет Git для Windows, я решил указать, что он включает в себя winpty
, который выглядит вполне читабельным.
$ winpty echo test
test
$ site="Default Web Site"
$ winpty 'C:\Windows\System32\inetsrv\appcmd' list site "${site}" /text:ID
1