web-dev-qa-db-ja.com

Git for WindowsでのBash:CMD.exe / Cで引数を指定してコマンドを実行するときの奇妙さ

これは問題というよりは厄介なことですが、ここでセマンティクスを理解したいと思います。

私がしたいのは、一時的なコマンドで任意のコマンドを実行することです-それ自体がbashセッションの下で実行されているプロンプトセッション。

一部のコマンドは期待どおりに機能するのに対し、他のコマンドはそれほど機能しないため、私の成功率は50/50です。

問題mayは、引数が適切に整列していない(つまり、引数が欠落しているかマージされている)ことにあると思います

一連のコマンドと応答によって、weirdの意味を説明しようと思います。 (Wordtestを画面に印刷しようとしています。)

私はこれらをGNU bash、バージョン3.1.0(1)-リリース(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:\>

2回目の試み:

$ cmd '/c echo test'
test"

3回目の試み:

$ cmd "/c echo test"
test"

4番目の試み:

$ cmd /c\ echo\ test
test"

5回目の試み:

$ cmd "/c echo" test
'echo" test' is not recognized as an internal or external command,
operable program or batch file.

これは私には直感的ではなく、私を夢中にさせるので、上記の動作へのポインタや洞察を本当に感謝します!

編集:これに似ているように見える 別の質問 がありますが、主にバッチの実行に関するものであるため、実際にはそうではありません引数を必要としないCMD/Cを介したファイル。

Windowsコマンドラインアプリに引数を適切に提供する方法についての私の質問には実際には答えていません。例はCMD/Cに関するものですが、ここでの答えは他の多くのWindowsコマンドラインアプリにも適用できます。

26
Arca Artem

これは実際にはReleaseNotesファイル(インストールされているGit for Windowsの最上位フォルダーにあります)に記載されています。

また、WindowsプログラムのWindowsパスを渡すには、MSysスタイルのPOSIXパスについての手がかりがないため、特別な注意を払う必要があります。$(cmd // c echo "$ POSIXPATH")のようなものを使用できます。

cmd //c echo testを使用すると、期待どおりに機能します。

$ cmd //c echo test
test

原因は、posixパスが最終的にgitユーティリティに正しく渡されるようにすることです。このため、Git for Windowsには、コマンド引数に影響を与える変更されたMSYSレイヤーが含まれています。 Git forWindowsで提供されるbashシェルとツールをWindows用の汎用UNIXツールとして使用することは意図されていないことに注意してください。汎用のUNIXスタイルのツールセットが必要な場合は、MSYSまたはcygwinをインストールする必要があります。 Git Bash Shellは、gitを操作するように設定されており、場合によってはそれが表示されます。

36
patthoyts

この記事を読んだ後、私は私のために働く解決策を見つけました:

$ cat gvim.sh
cmd << EOD
gvim $@
EOD
$

Windows 8.1、Git(バージョン1.9.5-preview20141217)、GNU bash、バージョン3.1.20(4)-リリース(i686-pc-msys)。

6
avb1003

私はWindows用のgnubashを使用して問題をほぼ再現することができます。

引用符なしで最初のフォームでパターンを完全に確立することはできません。 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を介して実行する可能性のあるほとんどすべてのコマンド文字列で機能するはずです。

3
dbenham

Git-bashが/c引数をC:ドライブのように扱うことに気づきました。

C:\Windows\system32\cmd.exe C:/ echo test

dbenham found として二重引用符が追加されます。これはtest"をエコーし​​ます。例:

cmd /c\ echo\ test

Git-bashとCygwinBashで機能するには、同じ行(スクリプト)が必要でした。動作する唯一の方法は

cmd /c\ echo\ test\&rem\ 

(この行はスペースで終わる必要があることに注意してください)、および

cmd << EOC
echo test
EOC

したがって、/cの後のすべてのスペースをエスケープし、add\&rem\ 行の終わり(末尾のスペースを含む)、またはコマンドを ヒアドキュメント でラップする=。

これはすべて、おそらくgit-bashのバージョンと特定のコマンドに依存します。 :-(

2

Git for Windows バンドルを使用しているとおっしゃっていたので、 含まれているwinptyと指摘したいと思いますが、これはかなりのようです。読み取り可能。

$ winpty echo test
test

$ site="Default Web Site"
$ winpty 'C:\Windows\System32\inetsrv\appcmd' list site "${site}" /text:ID
1

これは1.9.5.msysgit.1で動作するようです

!foo=`bar`
cmd //c \\\\unc-path\\with\\slashes -args \"Quoted Arguments $foo\"
0
John Gietzen