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

1144 語
6 分
【Python】venvを使いながら環境変数PS1を設定してプロンプトを見やすくしたい

はじまり#

リサちゃん avatar
リサちゃん
あれぇ? 戻っちゃったぞ
135ml avatar
135ml
コイツが何かしらを捻じ曲げているな。

何が起きているのか#

シェル上で Bash の環境変数PS1をゴニョゴニョいじると、ターミナルにおける現在の状態(プロンプト)を見やすく表示することが可能です。

例えば下記の画像の1行目のような感じです。

しかし、 Python の開発などで使用するvenvによる仮想環境を有効化したり無効化すると、このPS1の内容が書き換わってしまい、せっかく見やすく設定したPS1の内容が見づらい状態に、文字色が白色に戻ってしまいます。 そこで今回は、venv使用時の環境変数PS1の設定について色々やっていきます。

今回の設定に利用したvirtualenvパッケージのバージョンは、20.28.1です。

PS1の内容の確認#

まず、各々の状態における環境変数PS1の内容を確認します。

venvをアクティベートした時の環境変数PS1の内容。

Terminal window
PS1='\[\](.venv) \[\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$ \[\]\[\]'

venvを非アクティベートした時の環境変数PS1の内容。

Terminal window
PS1='\[\]\[\]\[\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$ \[\]\[\]\[\]'

そして、今回はこのような形式でPS1を設定して、ターミナルの状態を表示を見やすくしたいと思います。

Terminal window
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を作成してアクティベートする時の実行コマンドはこんな感じにします。

Terminal window
python -m venv .venv
source .venv/bin/activate

.venv/bin/activateのファイルの中身はこんな感じになっていました。PS1を設定している部分が見つかったので、この設定に対して何かしてあげれば良さそうです。venvactivateする時もdeactivateする時もdeactivate関数は実行されるみたいですね。

Terminal window
# 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 variables
deactivate 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/.venv
fi
_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 bash
if [ -n "${PYTHONHOME:-}" ] ; then
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
unset PYTHONHOME
fi
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}" # <--- activateする時に通る
PS1='(.venv) '"${PS1:-}"
export PS1
VIRTUAL_ENV_PROMPT='(.venv) '
export VIRTUAL_ENV_PROMPT
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

上記の.venv/bin/activateのファイルにおいて、どうやら_OLD_VIRTUAL_PS1という Bash 環境変数の中にvenvを有効化する前のPS1の内容が入るみたいです。 なので、今回はedit-ps1-envという関数を作って、.venv/bin/activateが終了した後に実行したいと思います。

Terminal window
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
}

そして、エイリアスを作成します。

Terminal window
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の有効化および無効化の後の両方で、プロンプトの文字色が自分の設定したい状態になりました。

Terminal window
py-va
py-vd

まとめ#

今回は、 Python でvenvを利用する際に、 Bash のプロンプトの表示色を保持するための設定方法を紹介しました。

sedを使って設定する方法も考えてみましたが、.venv/bin/activateのファイル内にある、venvのディレクトリ名が出現する場所が変わってしまうと設定が面倒なことになりそうでした。なので、.venv/bin/activateの実行後に別途設定する方法がメンテしやすいと思います。

これで仮想環境を有効化しているかどうかを一目で確認出来るようになりました。開発体験が快適になりそうです。

おしまい#

リサちゃん avatar
リサちゃん
よしよし、これでいいんだよ
135ml avatar
135ml
これで捻じ曲げ直したな。

以上になります!

記事を共有

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

【Python】venvを使いながら環境変数PS1を設定してプロンプトを見やすくしたい
https://endorphinbath.com/posts/python-venv-with-ps1-env/
著者
kinkinbeer135ml
公開日
2025-02-05
ライセンス
CC BY-NC-SA 4.0
関連記事 スマート
1
【Python】シェル上で出力した文字列で濁点が分かれてしまった文字(結合文字)を濁音に直すスクリプト
Code シェル上でファイル名などを出力した際に、バがバになってしまう場合があります。それをいちいち手作業で直すのがしんどいので、直してくれるスクリプトを作りました。テストコードもあります。
2
【Python】複数の区切り文字を指定して文字列を配列に分割する
Code Pythonで文字列を配列に分割するスクリプトを掲載します。分割文字は配列で指定するように作っています。
3
【Python】inputを使った処理をpytestでunittestしたい(monkeypatchでmockする)
Code Pythonスクリプトをpytestする時に、input()のようなビルトイン関数が入っている時にmockする方法を紹介します。monkeypatchを使用します。
4
【Python】pytestで同じディレクトリのモジュールをimportして、"ModuleNotFoundError: No module named"を出さなくする
Code Pythonスクリプトをpytestするとき、"ModuleNotFoundError: No module named"が表示されてしまった場合、この記事の方法でそのエラーが解決するかも。
5
【Python】Pydanticのvalidatorが非推奨だからfield_validatorを使って2段階バリデーションを実装する
Code @validatorはdeprecatedになってるし、@field_validatorにはpreとかalwaysフラグが無いから、from pydantic.functional_validators import field_validatorでインポートしたfield_validatorを使用する方法と、BeforeValidatorとAfterValidatorをAnnotateの中に入れる実装方法を試した。
ランダム記事 ランダム
Profile Image of the Author
kinkinbeer135ml
SIerをやめて、プログラミングを勉強しています。※Amazonアソシエイトに参加しています。
お知らせ
私のブログへようこそ!これはサンプルのお知らせです。
音楽
カバー

音楽

再生中なし

0:00 0:00
歌詞なし
カテゴリ
タグ
サイト統計
記事
287
カテゴリー
8
タグ
93
総文字数
486,174
運用日数
0
最終活動
0 日前

目次