🦁

Dev Container の bash プロンプトにいろいろ表示させる設定(ChatGPTもあるよ)

2023/04/20に公開

こんなDockerfileになりました

FROM node:lts-bullseye-slim AS dev
RUN apt update && apt install git vim curl -y && apt clean

RUN echo "source /usr/share/bash-completion/completions/git" >> ~/.bashrc

WORKDIR /usr/share/bash-completion/completions

RUN curl -O https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh
RUN curl -O https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash
RUN chmod a+x git*.*
RUN ls -l $PWD/git*.* | awk '{print "source "$9}' >> ~/.bashrc

RUN echo "GIT_PS1_SHOWDIRTYSTATE=true" >> ~/.bashrc
RUN echo "GIT_PS1_SHOWUNTRACKEDFILES=true" >> ~/.bashrc
RUN echo "GIT_PS1_SHOWUPSTREAM=auto" >> ~/.bashrc

RUN echo 'export PS1="\[\033[01;32m\]\u@\h\[\033[01;33m\] \w \[\033[01;31m\]\$(__git_ps1 \"(%s)\") \\n\[\033[01;34m\]\\$ \[\033[00m\]"' >> ~/.bashrc

コンテナ起動後のプロンプトは最初から下記のような状態になります。いいですね!

bash

解説

以下、順を追って内容をひもといていきます。

イメージの指定と最低限のコマンドをインストール

FROM node:lts-bullseye-slim AS dev
RUN apt update && apt install git vim curl -y && apt clean

ベースイメージを指定してapt update、最低限必要なgitvimcurlをインストールします。
特にcurlはこのあとのステージで必要になるので必ずインストールします。他のコマンドはご利用の目的に合わせてよしなにしてください。

基本的なGitのコマンド補完を設定

RUN echo "source /usr/share/bash-completion/completions/git" >> ~/.bashrc

デフォルトのGit補完スクリプトを読み込むようにします。
ただしこのスクリプトだけでは機能が不足しているので、以降の処理でプロンプト表示のカスタマイズや、より高度な補完機能が使えるようにします。

作業ディレクトリの変更

WORKDIR /usr/share/bash-completion/completions

このあとのステージでgit-prompt.shgit-completion.bashのダウンロード先とするため、前の手順のcompletionディレクトリを作業ディレクトリにします。

git-completionのダウンロードと権限付与

RUN curl -O https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh
RUN curl -O https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash
RUN chmod a+x git*.*

先ほど変更したWORKDIRへ、git-prompt.shgit-completion.bashをダウンロードします。
ダウンロード後はchmodで実行権限を付与します。

ダウンロードしたスクリプトの実行指示を書き込み

RUN ls -l $PWD/git*.* | awk '{print "source "$9}' >> ~/.bashrc

実行権限の付与まで終えたスクリプトファイルをls -lで列挙し、awkを使ってsource {ファイル名}の形式で.bashrcへ書き込みます。
(ls -lの出力で、9番目($9)の項目がファイル名になります。)

ブランチの状態表示オプションを設定

RUN echo "GIT_PS1_SHOWDIRTYSTATE=true" >> ~/.bashrc
RUN echo "GIT_PS1_SHOWUNTRACKEDFILES=true" >> ~/.bashrc
RUN echo "GIT_PS1_SHOWUPSTREAM=auto" >> ~/.bashrc

プロンプトに表示するブランチ関連のオプションを指定します。各オプションの機能は下表をご参考ください。

オプション 内容
GIT_PS1_SHOWDIRTYSTATE ステージされていない変更がある時に (*) を、 ステージされた変更がある時に (+) を、プロンプトのブランチ名の右に表示します。
GIT_PS1_SHOWUNTRACKEDFILES untracked files(新しく追加したファイル) がある時に ‘%’ を、プロンプトのブランチ名の右に表示します。
GIT_PS1_SHOWUPSTREAM 現在のブランチと、そのブランチが追跡しているリモートブランチ(upstream)との差分を表示します。(=: upstreamと同期、<: upstreamの方が進んでいる、>: upstreamより進んでいる)

環境変数PS1の設定

RUN echo 'export PS1="\[\033[01;32m\]\u@\h\[\033[01;33m\] \w \[\033[01;31m\]\$(__git_ps1 \"(%s)\") \\n\[\033[01;34m\]\\$ \[\033[00m\]"' >> ~/.bashrc

環境変数PS1に表示形式を表すフォーマットを指定し、プロンプト表示をカスタマイズします。

まとめ

以上です。

個人的にDev Containerで開発する機会が多い(ローカルマシンにいろいろ入れたくない)のですが、ローカルの環境と比べてプロンプトが殺風景なのがずっと気になっていました。
今回あらためてコンテナ開発時のプロンプトのカスタマイズ方法をまとめられましたので、自分の開発環境にもどんどん適用していこうと思います。

最後まで読んでいただき、ありがとうございました。
ではまた!

参考記事

おまけ

記事中でPS1に設定している値はほぼ参考記事から拝借したものですが、不勉強ながら気になったのでChatGPT(3.5)さんの力を借りて中身の解体を試みました。

それっぽい回答は得られたのですが、例によって内容が間違っている可能性があることと、記事の本筋から外れるため、真偽を深掘りすることは今回は割愛しております。

興味のある方は下記のセクションをご覧ください。

ChatGPTとのやりとり

Q.1

以下のようなコマンドで環境変数PS1の値を設定し、プロンプト表示をカスタマイズしようとしています。
この環境変数PS1に設定している文字列の意味を教えてください。
その際、事実のみを報告してください。

echo 'export PS1="\[\033[01;32m\]\u@\h\[\033[01;33m\] \w \[\033[01;31m\]\$(__git_ps1 \"(%s)\") \\n\[\033[01;34m\]\\$ \[\033[00m\]"' >> ~/.bashrc

A.1

このコマンドは、ユーザーの.bashrcPS1環境変数をカスタマイズした値を追加するものです。

PS1はBashシェルで使用される環境変数で、プロンプトの表示形式を定義します。以下は、このコマンドで設定されている文字列の意味です。

\[\033[01;32m\]: 文字色を緑色に設定するエスケープシーケンス。
\u@\h: ユーザー名とホスト名を表示する。
\[\033[01;33m\]: 文字色を黄色に設定するエスケープシーケンス。
\w: 現在の作業ディレクトリを表示する。
\[\033[01;31m\]\$(__git_ps1 \"(%s)\"): Gitリポジトリがある場合、カレントブランチ名を表示する。Gitリポジトリでない場合は何も表示しない。
\\n: 改行する。
\[\033[01;34m\]\\$: 文字色を青色に設定し、ユーザー権限でログインしている場合は$、管理者権限でログインしている場合は#を表示する。
\[\033[00m\]: テキストの色をリセットするエスケープシーケンス。

これにより、Bashのプロンプトが緑色でユーザー名とホスト名、黄色で現在の作業ディレクトリ、Gitリポジトリがある場合はカレントブランチ名を含んだ形式で表示されるようになります。

Q.2

\[\033[01;31m\]\$(__git_ps1 \"(%s)\")で指定している\[\033[01;31m\]の部分も、何らかの色を指定していますか?

A.2

はい、\[\033[01;31m\]は赤色を指定しています。\[\033[はエスケープシーケンスの開始を示し、\033はエスケープキーを押すことで入力されるASCIIコードの表現で、この部分を含む文字列がエスケープシーケンスであることを示しています。[01;31mはテキストのスタイルと色を指定するためのANSIエスケープコードで、01は太字、31は赤色を表します。\]はエスケープシーケンスの終了を示し、この部分を含む文字列がエスケープシーケンスであることを終了します。

参考文献:

Bash Prompt HOWTO: 6.1 Colours

Q.3

[01;31m01は太字、31は赤色をわかりましたが、mは何ですか?

A.3

m はANSIエスケープシーケンスの終端を表すコードです。これにより、文字列内で定義されたテキストの色やスタイルが適用されるようになります。例えば、\[\033[01;31m\]は文字列を太字の赤色に変更し、\[\033[00m\]は元のテキストスタイルに戻します。\033はエスケープシーケンスの開始を示し、[0;0;0mのようなコードは、それに続くスタイル定義を行うために使用されます。

Discussion