Git for Windows 2.xでプロンプトの設定(PS1)にブランチ名と改行を入れるとsyntax errorになる
Git for Widnows 2系に上げてから、設定(PS1)にブランチ名と改行を入れるとsyntax errorに
なるようになった。
対処方法がわからなかったので、しばらく、改行を外していて放置してた。
現象
bash: command substitution: line 1: syntax error near unexpected token `)' bash: command substitution: line 1: `__git_ps1)'
条件
- Git for Widnows 2.xを使用してる。
- PS1に
__git_ps1
でブランチ名を設定してる。 - PS1に改行(
\n
)を設定している。
例
export PS1='\w$(__git_ps1)\n\$ '
問題にならない条件
Git for Widnows 2.xでも以下の条件ではsyntax errorにならない
- ブランチ名がない場合
export PS1='\w\n\$ '
- 改行の設定がない場合
export PS1='\w$(__git_ps1)\$ '
- ブランチ名がない場合
Git for Widnows 1.xを使っている場合はsyntax errorにならない
- Linuxで、Gitを使ってる場合はsyntax errorにならない
環境
以下の環境だとsyntax errorになる。
調査
LinuxではGit 1.x、2.xでも発生しないから、Git for Widnowsの問題だろう。
WindowsだとGit 1.xでは問題なかった。
2.xになってから、なにか変更があったっぽい。
ぐぐったら事例は出てきた。
PS1 bash command substitution not working on windows 10
'\n$'
を$'\n$ '
にすればいいみたい。
なんで?
Cygwinの事例なら、原因が書いてあった。
Cygwin のプロンプトに Git のブランチを表示する(シンタックスエラーが発生した場合の対策あり)
構文解析でエラー
Cygwin 環境では $PS1 のコマンド置換でシンタックスエラーが出ることがあります。
-bash: command substitution: line 1: syntax error near unexpected token `)'
-bash: command substitution: line 1: `__git_ps1)'
これは改行コード CR を無視する Cygwin 独自のシェルオプション igncr による影響の
ようです。igncr が設定されている場合,$PS1 内で $( ) 形式のコマンド置換の後に
\n が続くと構文解析に失敗してしまいます。バッククォートによる旧式のコマンド置換
ではこの現象は発生しません。
CRが悪さしてるのか。
igncrの設定がGit for Widnows 2.xから変わった?
確認してみる。
Git for Windows 1.9.4の環境
$ git --version git version 1.9.4.msysgit.1
$ bash --version GNU bash, version 3.1.0(1)-release (i686-pc-msys) Copyright (C) 2005 Free Software Foundation, Inc.
$ set -o allexport off braceexpand on emacs on errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off
igncrの項目は無い。無いけど有効になっているのか?
Git for Windows 2.11.1
$ set -o |grep igncr igncr off
offだな。
2.xでなにが変更になったかは、確認できず。。。
対処
対処は、Cygwin のプロンプトに Git のブランチを表示する(シンタックスエラーが発生した場合の対策あり)に載っているもののうちの以下の2つ。
バッククォート形式にする
export PS1='\w`__git_ps1`\n\$ '
改行を$'\n'にする
export PS1='\w$(__git_ps1)'$'\n$ '
後者を選択。
$'\n'ってなに?
BASHより
$'string' の形式を持つ単語は特殊な扱いを受けます。 この単語は string に展開され、
それから ANSI C 標準で仕様が決められている、 バックスラッシュでエスケープされている
文字に置き換えられます。 バックスラッシュエスケープシーケンスは、 (もし存在すれば)
以下のようにデコードされます:(省略)
- \n
改行