source
my -dには次のコードがあります。.shellrc
PATH="${PATH}:${HOME}/perl5/bin"
PATH="${PATH}:${HOME}/.bin"
export PATH
ただし、別のコードを変更してからsource
このファイルを変更すると、各ソースへのパスが長くなり、ソースがすでに存在するたびにソースが追加されます。これが起こらないようにするにはどうすればよいですか?
答え1
add_to_PATH () {
for d; do
d=$({ cd -- "$d" && { pwd -P || pwd; } } 2>/dev/null) # canonicalize symbolic links
if [ -z "$d" ]; then continue; fi # skip nonexistent directory
case ":$PATH:" in
*":$d:"*) :;;
*) PATH=$PATH:$d;;
esac
done
}
add_to_PATH ~/perl5/bin ~/.bin
シンボリックリンク正規化行はオプションです。削除した場合は、次の行も削除するか(存在しないディレクトリを維持したい場合)、次の行に変更します。
if ! [ -d "$d" ]; then continue; fi
シンボリックリンク正規化方法は、この関数によって追加されたディレクトリ間の一意性のみを保証することに注意してください。また、2 つの場所にマウントされた NFS ディレクトリや Linux バインドマウントなどのエッジケースも処理しません。
答え2
追加する前に、すでにパスにあることを確認する「このディレクトリをパスに追加」コマンドをテストできますが、foo
そうすることで大きな利点を得ることはできません。
第一に、反復要素を取り付けるのに比べてテスト自体のコストが高い。第二に、パス内で最初に一致する実行ファイルが実行され続けるため、パスの後続の冗長要素は、指定されたコマンドが実行されたときに実行されるエントリには影響しません。最後に、ほとんどのシェルは以前のパスヒットをハッシュテーブルにキャッシュするため、パスがmy_command
2回目の実行時にパスを取得することはありません。
重複した項目を追加しないことで得られる唯一のことは、パスがよりきれいに見えることです。しかし、ほとんどのルートは最初からかなり見苦しいです。この審美的な目標が本当に重要な場合は、どのシェルを使用しているかを教えてください。
答え3
私が使用する機能は、OS Xのfink初期化スクリプトから派生しました(したがってクレジットはfink開発者に戻ります)。うまく動作し、いつでも.bash_profileリソースを再インポートできます。どのように動作するか尋ねないでください...私はこれがこれであることを知っているだけです:)
# define append_path and prepend_path to add directory paths, e.g. PATH, MANPATH
# add to end of path
append_path()
{
if ! eval test -z "\"\${$1##*:$2:*}\"" -o -z "\"\${$1%%*:$2}\"" -o -z "\"\${$1##$2:*}\"" -o -z "\"\${$1##$2}\"" ; then
eval "$1=\$$1:$2"
fi
}
# add to front of path
prepend_path()
{
if ! eval test -z "\"\${$1##*:$2:*}\"" -o -z "\"\${$1%%*:$2}\"" -o -z "\"\${$1##$2:*}\"" -o -z "\"\${$1##$2}\"" ; then
eval "$1=$2:\$$1"
fi
}
$PATH
次のようにorに追加するか、前に追加するために使用できます$MANPATH
(同様の型の変数で機能します$PATH
)。
prepend_path PATH $macPortsDir/sbin
prepend_path MANPATH $macPortsDir/man
答え4
あなたができることの1つは、環境変数を保護として使用することです。だから環境を__<your script>__path_added
。
スクリプトでパスを追加する前に、パスが設定されていることをテストできます。 Cヘッダーガードに似ています。