さて、tmuxを使っていたり、シェル設定を書き換えてsourceしたりなど、PATHやLD_LIBRARY_PATHなどのパス系環境変数の記述が重複してしまうことがよくあります。
これを解決するためのメモ。
参考はこちら。というか完全にそのまま。
zsh で環境変数 LD_LIBRARY_PATH、INCLUDE などの重複パスを除去する – キーボードをたたくとき
zshrcやzshenvに下記のような記述をすればOKです。
typeset -T LD_LIBRARY_PATH ld_library_path; typeset -U ld_library_path typeset -T LIBRARY_PATH library_path; typeset -U library_path typeset -T CPATH cpath; typeset -U cpath
どういう意味かは参考サイトの通りです。
また、特にPATHなどに関しては以下の記述で重複除去ができます。
typeset -U path cdpath fpath manpath
ところで、パス記述の重複ってパフォーマンスには影響するのかな。
つまり、実際のパス探索の段階で、すでに見たところをまた見に行ったりするんでしょうか。
だとすると重複除去は絶対必要ですねー。
あと、bashで同じことをしたい場合はどうすればいいんでしょう。
こんなかんじで重複除去自体はできなくはないですが、
$ PATH=c:b:c:a:b:a $ PATH=`echo $PATH | sed "s/:/\n/g" | sort -u | paste -sd ":"` $ echo $PATH a:b:c
記述順が変化してしまい、実際のパス探索の順序が変わってしまい、イケてないかんじです。
力技でできないことはないけど・・・スマートにできないものか。
追記。bashやshでの重複除去を力づくでやってみたので、興味があれば続きを参照。
力づくで重複除去やるシェルスクリプト書いてみた。
bashの場合。ハイライト部分はzshやsh版との違いのある部分。
#!/bin/bash TMP=(`echo $PATH | sed "s/:/ /g"`) RESULT=${TMP[0]} for P in ${TMP[@]}; do if test $(echo $RESULT | grep -c $P) -eq 0; then RESULT=$RESULT:$P fi done export PATH=$RESULT
うごかすと、実際のパス探索順を保って重複除去できていて、イケてる感じです。
ただし見ての通り、例えばPATHが空の場合などの例外パターンのハンドリングはほとんどしていません。
$ PATH=c:a:b:c:b:a $ ./uniqpath.sh $ echo $PATH c:a:b
shの場合。
#!/bin/sh TMP=`echo $PATH | sed "s/:/ /g"` RESULT=`echo $TMP | sed "s/\s.\+\$//g"` #RESULT=`echo $TMP | sed "s/ /\n/g" | head -n 1` #これでも可 for P in $TMP; do if test $(echo $RESULT | grep -c $P) -eq 0; then RESULT=$RESULT:$P fi done export PATH=$RESULT
特に意味はないけどzsh版。ほとんどbash版と同じだけど、配列の扱いが微妙に違うため・・・
#!/bin/zsh TMP=(`echo $PATH | sed "s/:/ /g"`) RESULT=$TMP[1] for P in ${TMP[@]}; do if test $(echo $RESULT | grep -c $P) -eq 0; then RESULT=$RESULT:$P fi done export PATH=$RESULT
シェルの違いによるびっみょーな挙動の違い、しんどい。。
RESULTの初期値は、最終的なPATHの先頭や末尾にコロンがつくのがイケてないので、番人として設定してるわけです。そこ気にしないならもっとすっきりいきそう。
おさかなを自称しながらfishで試さない点がオチです。