Назад | Перейти на главную страницу

Удалите повторяющиеся записи из переменной PATH

Я часто изменяю свой .bashrc, а затем использую его. Однако, когда у меня есть такие вещи, как export PATH="~/bin:~/perl5/bin:$PATH" в моем файле, затем PATH переменная окружения увеличивается каждый раз, когда я загружаю файл.

Например, при первом использовании .bashrc PATH переменная состоит из ~/bin:~/perl5/bin:/usr/bin:/bin.

Во второй раз он состоит из ~/bin:~/perl5/bin:~/bin:~/perl5/bin:/usr/bin:/bin.

В третий раз он состоит из ~/bin:~/perl5/bin:~/bin:~/perl5/bin:~/bin:~/perl5/bin:/usr/bin:/bin.

Есть ли простой способ заставить его добавлять только то, чего еще нет в PATH?

Используйте функцию pathmunge (), доступную в большинстве дистрибутивов. /etc/profile:

pathmunge () {
if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
   if [ "$2" = "after" ] ; then
      PATH=$PATH:$1
   else
      PATH=$1:$PATH
   fi
fi
}

редактировать: Для zsh пользователи, typeset -U <variable_name> будет дедуплицировать записи пути.

У меня была эта проблема, поэтому я использовал комбинацию методов, перечисленных на Переполнение стека вопрос. Ниже приводится то, что я использовал для вывода фактической переменной PATH, которая уже была установлена, поскольку я не хотел изменять базовый сценарий.

    tmppath=(${PATH// /@})
    array=(${tmppath//:/ })
    for i in "${array[@]//@/ }"
    do
        if ! [[ $PATH_NEW =~ "$i" ]]; then
            PATH_NEW="${PATH_NEW}$i:";
        fi
    done;
    PATH="${PATH_NEW%:}"
    export PATH
    unset PATH_NEW

Вы всегда можете немного оптимизировать это, но у меня в оригинале был дополнительный код для отображения того, что происходило, чтобы убедиться, что он правильно устанавливает переменные. Также следует отметить, что я выполняю следующие

  1. заменить любой символ ПРОБЕЛ на символ @
  2. разбить массив
  3. пройти через массив
  4. замените любые символы @ в строке элемента пробелом

Это сделано для того, чтобы я мог обрабатывать каталоги с пробелами в (домашние каталоги Samba с именами пользователей Active Directory могут иметь пробелы!)

Только одна строка:

for i in $(echo $PATH|tr ":" "\n"|sort|uniq);do PATH_NEW="${PATH_NEW}$i:";done;PATH="${PATH_NEW%:}"

Укажите свой путь явно.

Я могу придумать два разных способа решить эту проблему. Первый - начать ваш .bashrc строкой, которая явно устанавливает ваш базовый PATH, таким образом, каждый раз, когда вы его отправляете, он сбрасывается до базового значения до добавления дополнительных каталогов.

Например, добавьте:

# Reset the PATH to prevent duplication and to make sure that we include
# everything we want.
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Кроме того, вы можете проверить наличие элемента, прежде чем добавлять его в путь. Для этого вы должны использовать что-то вроде:

if ! [[ $PATH =~ '~/perl5/bin' ]]
then
    PATH="~/perl5/bin:$PATH"
fi

Однако последнее имеет тенденцию становиться немного повторяющимся, если вы добавляете много записей, поэтому я предпочитаю придерживаться первого. Если вы хотите использовать это и планируете добавить много записей, было бы разумно написать функцию bash для ее обработки.

Примечание: второй вариант может работать только так, как написано в современных версиях bash. Поддержка регулярных выражений не является функцией Bourne Shell (/ bin / sh) и может отсутствовать в других оболочках. Кроме того, использование кавычек может не понадобиться или даже вызвать проблемы в некоторых новейших версиях bash.

Вот мое решение: PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")

Хороший легкий лайнер, который не оставляет следов: