Я часто изменяю свой .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
Вы всегда можете немного оптимизировать это, но у меня в оригинале был дополнительный код для отображения того, что происходило, чтобы убедиться, что он правильно устанавливает переменные. Также следует отметить, что я выполняю следующие
Это сделано для того, чтобы я мог обрабатывать каталоги с пробелами в (домашние каталоги 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/")
Хороший легкий лайнер, который не оставляет следов: