【Python】venvを使いながら環境変数PS1を設定してプロンプトを見やすくしたい
はじまり


何が起きているのか
シェル上で Bash の環境変数PS1をゴニョゴニョいじると、ターミナルにおける現在の状態(プロンプト)を見やすく表示することが可能です。
例えば下記の画像の1行目のような感じです。

しかし、 Python の開発などで使用するvenvによる仮想環境を有効化したり無効化すると、このPS1の内容が書き換わってしまい、せっかく見やすく設定したPS1の内容が見づらい状態に、文字色が白色に戻ってしまいます。
そこで今回は、venv使用時の環境変数PS1の設定について色々やっていきます。
今回の設定に利用したvirtualenvパッケージのバージョンは、20.28.1です。
PS1の内容の確認
まず、各々の状態における環境変数PS1の内容を確認します。
venvをアクティベートした時の環境変数PS1の内容。
PS1='\[\](.venv) \[\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$ \[\]\[\]'venvを非アクティベートした時の環境変数PS1の内容。
PS1='\[\]\[\]\[\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$ \[\]\[\]\[\]'そして、今回はこのような形式でPS1を設定して、ターミナルの状態を表示を見やすくしたいと思います。
export PS1='\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\] $(_current_branch)\[\033[00m\]\[\033[01;35m\]\$\[\033[00m\] 'venv実行時に何が起きているのか
今回、venvを作成してアクティベートする時の実行コマンドはこんな感じにします。
python -m venv .venvsource .venv/bin/activate.venv/bin/activateのファイルの中身はこんな感じになっていました。PS1を設定している部分が見つかったので、この設定に対して何かしてあげれば良さそうです。venvをactivateする時もdeactivateする時もdeactivate関数は実行されるみたいですね。
# This file must be used with "source bin/activate" *from bash*# You cannot run it directly
deactivate () { # reset old environment variables if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then # <--- deactivateする時に通る PATH="${_OLD_VIRTUAL_PATH:-}" export PATH unset _OLD_VIRTUAL_PATH fi if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" export PYTHONHOME unset _OLD_VIRTUAL_PYTHONHOME fi
# Call hash to forget past commands. Without forgetting # past commands the $PATH changes we made may not be respected hash -r 2> /dev/null
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then PS1="${_OLD_VIRTUAL_PS1:-}" export PS1 unset _OLD_VIRTUAL_PS1 fi
unset VIRTUAL_ENV unset VIRTUAL_ENV_PROMPT if [ ! "${1:-}" = "nondestructive" ] ; then # Self destruct! unset -f deactivate fi}
# unset irrelevant variablesdeactivate nondestructive
# on Windows, a path can contain colons and backslashes and has to be converted:if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then # transform D:\path\to\venv to /d/path/to/venv on MSYS # and to /cygdrive/d/path/to/venv on Cygwin export VIRTUAL_ENV=$(cygpath /home/user/NotionSynchronizer/.venv)else # use the path as-is export VIRTUAL_ENV=/home/user/NotionSynchronizer/.venvfi
_OLD_VIRTUAL_PATH="$PATH"PATH="$VIRTUAL_ENV/"bin":$PATH"export PATH
# unset PYTHONHOME if set# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)# could use `if (set -u; : $PYTHONHOME) ;` in bashif [ -n "${PYTHONHOME:-}" ] ; then _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" unset PYTHONHOMEfi
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then _OLD_VIRTUAL_PS1="${PS1:-}" # <--- activateする時に通る PS1='(.venv) '"${PS1:-}" export PS1 VIRTUAL_ENV_PROMPT='(.venv) ' export VIRTUAL_ENV_PROMPTfi
# Call hash to forget past commands. Without forgetting# past commands the $PATH changes we made may not be respectedhash -r 2> /dev/null上記の.venv/bin/activateのファイルにおいて、どうやら_OLD_VIRTUAL_PS1という Bash 環境変数の中にvenvを有効化する前のPS1の内容が入るみたいです。
なので、今回はedit-ps1-envという関数を作って、.venv/bin/activateが終了した後に実行したいと思います。
function _current_branch() { _git_branch=$(git branch --show-current 2>/dev/null) && echo "[branch: $_git_branch] "}
function edit-ps1-env() { _my_ps1='\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\] \[\033[01;33m\]$(_current_branch)\[\033[00m\]\[\033[01;36m\]\$\[\033[00m\] ' case ${1} in --activate | -a) export _OLD_VIRTUAL_PS1="$_my_ps1" _my_venv_dir='.venv' PS1="\[\033[01;31m\]($_my_venv_dir)\[\033[00m\] ""${_my_ps1:-}" return 0 ;; --deactivate | -d) # nothing to do return 0 ;; *) echo "[ERROR] invalid options: '${1}'" return 1 ;; esac}そして、エイリアスを作成します。
alias py-ve='python -m venv .venv'alias py-va='source .venv/bin/activate; edit-ps1-env -a;'alias py-vd='deactivate; edit-ps1-env -d;'この状態でコマンドを実行してみます。すると、venvの有効化および無効化の後の両方で、プロンプトの文字色が自分の設定したい状態になりました。
py-vapy-vd
まとめ
今回は、 Python でvenvを利用する際に、 Bash のプロンプトの表示色を保持するための設定方法を紹介しました。
sedを使って設定する方法も考えてみましたが、.venv/bin/activateのファイル内にある、venvのディレクトリ名が出現する場所が変わってしまうと設定が面倒なことになりそうでした。なので、.venv/bin/activateの実行後に別途設定する方法がメンテしやすいと思います。
これで仮想環境を有効化しているかどうかを一目で確認出来るようになりました。開発体験が快適になりそうです。
おしまい


以上になります!
記事を共有
この記事が役に立ったなら、ぜひ他の人と共有してください!