2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

bashとzshで重複したPATH内のエントリ削除

Last updated at Posted at 2017-09-09

設定ファイル内で環境変数PATHの重複を削除する方法。

よく見かけるパターンだと、

  • パスに空白が含まれていたらそこで分割されてしまう
  • PATH=""だとエラーが生じる
  • pathmergeのような専用関数を通す必要がある

とちょっと不便な部分があったため作成。

bashの場合

# 連想配列が使えるかどうかチェック
if typeset -A &>/dev/null; then
  # 使える場合
  typeset -A _paths
  typeset _results
  while read -r _p; do
    if [[ -n ${_p} ]] && (( ${_paths["${_p}"]:-1} )); then
      _paths["${_p}"]=0
      _results=${_results}:${_p}
    fi
  done <<<"${PATH//:/$'\n'}"
  PATH=${_results/:/}
  unset -v _p _paths _results
else
  # 使えない場合はawkで
  typeset _p=$(awk 'BEGIN{RS=":";ORS=":"} !x[$0]++' <<<"${PATH}:")
  PATH=${_p%:*:}
  unset -v _p
fi

以上を.bashrcの最後に書いておく。

この方法では、最初のエントリだけが残る。
つまり、

/usr/local/bin:/usr/bin:/usr/local/bin

なら、

/usr/local/bin:/usr/bin

となる。

やっていることは単純。

  1. コロンを改行に置き換え
  2. 連想配列に登録
  3. 初めて出会った行ならにパスに追加

メリットとしては、

  • パスに空白やアスタリスクが含まれていても大丈夫
  • 順番を維持できる
  • 連想配列が使える(bash4.2以上)なら外部コマンドを使用しない

ということでちょっとお得かも。

zshの場合

typeset -Uを利用すれば自動で重複エントリ絞ってくれる。
変数の挙動そのものを変えるので、どこに書いても一緒。
.zshrcの最後に書くのが分かりやすくて良さげ。

typeset -U PATH
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?