背景
今までは何も考えずにbash_profile
内で環境変数PATH
に
export PATH="$PATH:$HOME/new/path/to/dir"
のようにディレクトリへのパスを追加していました。しかし、このように追加しているとログイン中に何度もsource
した時にパスが重複してしまうため、何とかしようと思ってググり試行錯誤した結果をここへ残します。
シェルスクリプトと説明
以下のようにしてbash_profile
内で新しいパスを追加、あるいは既存のパスを削除します。
# パスを追加する関数
pathadd() {
# 環境変数名を第一引数として受け取る
envname=$1
# 環境変数の中に格納されているパスを保存
eval envpath='$'$envname
# 第二引数として受け取った追加するパスの末尾から/を除き変数pathtoaddへ保存
pathtoadd="${2%/}"
# 最初に環境変数内をきれいにする
# (1) 連続するコロンがないか探し一つにまとめる
# (2) 先頭または末尾のコロンを削除する
eval $envname="$(echo $envpath | sed -r -e 's;:{2,};:;g' -e 's;^:|:$;;g')"
# ディレクトリが存在し、かつ環境変数内に受け取ったパスが存在しない場合のみ、パスを追加する
if [[ -d "$pathtoadd" && $(echo $envpath | grep -E -c "(^|:)$pathtoadd($|:)") -eq 0 ]]; then
# 第三引数としてafterが追加されているときは末尾にパスを追加
# それ以外のときは先頭に追加
if [ "$3" = "after" ]; then
eval $envname="$envpath:$pathtoadd"
else
eval $envname="$pathtoadd:$envpath"
fi
fi
}
# パスを削除する関数
pathrm() {
# 環境変数名を第一引数として受け取る
envname=$1
# 環境変数の中に格納されているパスを保存
eval envpath='$'$envname
# 第二引数として受け取った追加するパスの末尾から/を除き変数pathtormへ保存
pathtorm="${2%/}"
# 環境変数内から該当するパスを削除
# (1) パスが含まれている場合は空白へ変換する
# (2) 先頭または末尾にコロンがある場合は削除する
# (3) コロンが二連続する場合は一つ削除する
eval $envname="$(echo $envpath | sed -r -e "s;(^|:)$pathtorm(:|$);\1\2;g" -e 's;^:|:$;;g' -e 's;::;:;g')"
}
# 使用例
# 先頭へ追加
pathadd PATH "$HOME/.local/bin"
# 末尾へ追加
pathadd PATH "$HOME/MyProject/MySoftware/bin" after
パスの区切り文字がスラッシュ(/)なので、sedの文字置換でよく使われるスラッシュ(/)を使うことができません。ですので代わりにセミコロン(;)を使用しています。