Мне интересно, где новый путь должен быть добавлен к переменной среды PATH
. Я знаю, что это можно сделать, отредактировав .bashrc
(например), но неясно, как это сделать.
Сюда:
& Лт;!- язык: bash - >
export PATH=~/opt/bin:$PATH
или это?
export PATH=$PATH:~/opt/bin
PATH=$PATH:~/opt/bin
или
PATH=~/opt/bin:$PATH
в зависимости от того, хотите ли вы добавить ~ / opt / bin
в конце (для поиска по всем другим каталогам, в случае, если в нескольких каталогах есть программа с тем же именем) или в начале (для поиска перед всеми другие каталоги).
Вы можете добавить несколько записей одновременно. PATH = $ PATH: ~ / opt / bin: ~ / opt / node / bin
или изменения в работе заказа просто отлично. Не ставьте «экспорт» в начале строки, так как у него есть дополнительные осложнения (см. Ниже «Заметки о оболочках, отличных от bash»).
Если ваш PATH
создается разными компонентами, вы можете получить дубликаты записей. См. https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-be-viscovered-by-unix-which-command и https://unix.stackexchange.com/questions/40749/ удалить дубликаты-путь-путь-путь-путь-путь-путь-путь-путь-с-облицитировать-облицидировать.
Кстати, некоторые дистрибутивы автоматически помещают ~ / bin
в ваш PATH, если он существует.
Поместите строку, чтобы изменить PATH
в ~/.profile
или в ~/.bash_profile
, если это то, что у вас есть.
Обратите внимание, что ~/.bash_rc
не читается какой-либо программой, а ~/.bashrc
- это файл конфигурации интерактивных экземпляров bash. Вы не должны определять переменные среды в ~/.bashrc
. Правильное место для определения переменных среды, таких как PATH
, - это ~/.profile
(или~/.bash_profile
, если вас не волнуют оболочки, отличные от bash). Смотрите В чем разница между ними и какой из них я должен использовать?
Не помещайте его в / etc / environment
или ~/.pam_environment
: это не файлы оболочки, вы не можете использовать там замены типа $ PATH
. В этих файлах вы можете переопределять только переменную, а не добавлять к ней.
Вам не нужен export
, если переменная уже находится в среде: любое изменение значения переменной отражается в среде.& # 185; PATH
почти всегда в окружающей среде; все системы unix устанавливают это очень рано (обычно в самом первом процессе, на самом деле).
Во время входа в систему вы можете положиться на то, что PATH
уже находится в среде и уже содержит некоторые системные каталоги. Если вы и № 39;переписывание сценария, который может быть выполнен рано при настройке какой-либо виртуальной среды, Вам может потребоваться убедиться, что PATH
не пуст и экспортирован: если PATH
все еще не установлен, тогда что-то вроде PATH = $ PATH: / some / directory
установит для PATH
значение : / some / directory
, и пустой компонент в начале означает текущий каталог (как .: / some / directory
).
if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi
В bash, ksh и zsh export
является специальным синтаксисом, и оба PATH = ~ / opt / bin: $ PATH
и export PATH = ~ / opt / bin: $ PATH
делают правильные вещи даже. В других оболочках в стиле Bourne / POSIX, таких как dash (который во многих системах называется / bin / sh
), export
анализируется как обычная команда, что подразумевает два различия:
~
анализируется только в начале слова, за исключением заданий (см. https://unix.stackexchange.com/questions/25605/how-to-add-home-directory-path-to-be-discovered- by-unix-which-command/25704 для деталей);$ PATH
вне двойных кавычек [перерывов, если PATH
содержит пробел или \ [*?
](https://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters).Таким образом, в оболочках, таких как тире, < strike > export PATH = ~ / opt / bin: $ PATH
< / strike > устанавливает PATH
в буквальную строку ~ / opt / bin /:
, за которой следует значение PATH
до первого пространства.
PATH = ~ / opt / bin: $ PATH
(необходимое назначение) [не требует кавычек](https://unix.stackexchange.com/questions/68694/when-is-double-quoting-needary/68748 # 68748) и делает правильные вещи. Если вы хотите использовать export
в переносном сценарии, вам нужно написать export PATH = "$ HOME / opt / bin: $ PATH"
илиPATH = ~ / opt / bin: $ PATH; export PATH
для переносимости даже в оболочку Bourne, которая не принимает` export.
& # 185; Это не было правдой в оболочках Борна (как в реальной оболочке Борна, а не в современных оболочках в стиле POSIX), но в наши дни вы вряд ли столкнетесь с такими старыми снарядами. & Лт; / sub >
В любом случае работает, но они не делают то же самое: элементы PATH
проверяются слева направо. В вашем первом примере исполняемые файлы в ~ / opt / bin
будут иметь приоритет над установленными, например, в / usr / bin
, которые могут быть или не быть тем, что вы хотите.
В частности, с точки зрения безопасности, опасно добавлять пути вперед, потому что, если кто-то может получить доступ для записи к вашему ~ / opt / bin
, он может поместить, например, другое ls
в там, который вы бы тогда использовали вместо / bin / ls
, не замечая. Теперь представьте то же самое для ssh
или вашего браузера или выбора... (То же самое касается тройного размещения . на вашем пути.)
Меня смущает вопрос 2 (с тех пор как он исключен из вопроса, поскольку это было связано с несвязанным вопросом):
Какой работоспособный способ добавить больше путей на разные линии? Изначально я думал, что это может помочь:
& Лт;!--language: lang-bash - >
экспортировать PATH = $ PATH: ~ / opt / bin экспортировать PATH = $ PATH: ~ / opt / node / bin
но это не так, потому что второе назначение не только добавляется
~ / opt / node / bin
, но также и весьPATH
, ранее назначенный.Это возможный обходной путь:
& Лт;!--language: lang-bash - >
экспортировать PATH = $ PATH: ~ / opt / bin: ~ / opt / node / bin
но для удобочитаемости я бы предпочел иметь одно задание для одного пути.
Если вы говорите
PATH=~/opt/bin
это все , что будет в вашем PATH. PATH - это просто переменная среды, и если вы хотите добавить в PATH, вам нужно перестроить переменную именно с нужным содержимым. То есть то, что вы приводите в качестве примера к вопросу 2, это именно то, что вы хотите сделать, если я полностью не упустил суть вопроса.
Я использую обе формы в своем коде. У меня есть общий профиль, который я устанавливаю на каждом компьютере, на котором я работаю, который выглядит так, чтобы приспособиться к потенциально отсутствующим каталогам:
export PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11
# add optional items to the path
for bindir in $HOME/local/bin $HOME/bin; do
if [ -d $bindir ]; then
PATH=$PATH:${bindir}
fi
done
Пуленепробиваемый способ добавления / оценки
Есть много соображений, связанных с выбором добавления и добавления. Многие из них покрыты другими ответами, поэтому я не буду повторять их здесь.
Важным моментом является то, что, даже если системные сценарии не используют это (интересно, почему) * 1 < / sup >,
пуленепробиваемый способ добавления пути (например,.$ HOME / bin
) к переменной среды PATH
PATH="${PATH:+${PATH}:}$HOME/bin"
для добавления (вместо PATH = "$ PATH: $ HOME / bin"
)
а также
PATH="$HOME/bin${PATH:+:${PATH}}"
для предоплаты (вместо PATH = "$ HOME / bin: $ PATH"
)
Это позволяет избежать ложной передней / задней ободочной кишки, когда $ PATH
изначально пуст, что может иметь нежелательные побочные эффекты и может стать кошмаром , который трудно найти (этот ответ кратко касается случая awk
-way).
Объяснение (из Расширение параметра оболочки):
$ {параметр: + слово}
Если
parameter
является нулевым или не установленным, ничего не заменяется, в противном случае расширениеword
заменяется.
Таким образом, $ {PATH: + $ {PATH}:}
расширяется до:
PATH
является нулевым или неустановленным$ {PATH}:
, если установленPATH
.Примечание : Это для bash.
& Лт; hr >
* 1 < / sup > Я только что обнаружил, что сценарии типа devtoolset-6 / enable
действительно используют это,
$ cat /opt/rh/devtoolset-6/enable
# General environment variables
export PATH=/opt/rh/devtoolset-6/root/usr/bin${PATH:+:${PATH}}
...
Linux определяет путь поиска исполняемого файла с помощью переменной среды $ PATH
. Чтобы добавить каталог / data / myscripts в начало переменной среды $ PATH
, используйте следующее:
PATH=/data/myscripts:$PATH
Чтобы добавить этот каталог в конец пути, используйте следующую команду:
PATH=$PATH:/data/myscripts
Но предшествующего недостаточно, потому что когда вы устанавливаете переменную среды внутри скрипта, это изменение эффективно только внутри скрипта. Есть только два способа обойти это ограничение:
Примеры:
$HOME/myscript.sh
source $HOME/myscript.sh
Включение в основном включает «называемый» сценарий в сценарий «вызов». Это как #include в C. Так что это эффективно внутри сценария или программы «вызов». Но, конечно, это неэффективно в любых программах или скриптах, вызываемых вызывающей программой. Чтобы сделать его эффективным на всем пути цепочки вызовов, вы должны следовать настройке переменной среды с помощью команды экспорта.
Например, программа оболочки bash включает содержимое файла .bash_profile путем включения. Поместите следующие 2 строки в .bash_profile:
PATH=$PATH:/data/myscripts
export PATH
эффективно помещает эти 2 строки кода в программу bash. Таким образом, в bash переменная $ PATH включает $ HOME / myscript.sh
, и из-за оператора экспорта любые программы, вызываемые bash, имеют измененную переменную $ PATH
. А поскольку любые программы, которые вы запускаете из приглашения bash, вызываются bash, новый путь действует для всего, что вы запускаете из приглашения bash.
Суть в том, что для добавления нового каталога в путь необходимо добавить или добавить каталог к переменной среды $ PATH в скрипте, включенном в оболочку, и вы должны экспортировать переменную среды $ PATH
.
Дополнительная информация < a href = "http://www.troubleshooters.com/linux/prepostpath.htm" > here < / a >
В течение некоторого времени я держал при себе две функции pathadd
и pathrm
, которые помогают добавлять элементы в путь без необходимости беспокоиться о дублировании.
pathadd
принимает один аргумент пути и необязательный аргумент after
, который, если он предоставлен, будет добавлен к PATH
, в противном случае он предварительно добавляется.
Почти в каждой ситуации, если вы добавляете путь, вы, вероятно, хотите переопределить все, что уже есть в пути, поэтому я предпочитаю делать предукты по умолчанию.
pathadd() {
newelement=${1%/}
if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then
if [ "$2" = "after" ] ; then
PATH="$PATH:$newelement"
else
PATH="$newelement:$PATH"
fi
fi
}
pathrm() {
PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
}
Поместите их в любой скрипт, который вы хотите изменить в среде PATH, и теперь вы можете это сделать.
pathadd "/foo/bar"
pathadd "/baz/bat" after
export PATH
Вы гарантированно не добавите к пути, если он уже есть. Если вы хотите убедиться, что / baz / bat
находится в начале.
pathrm "/baz/bat"
pathadd "/baz/bat"
export PATH
Теперь любой путь можно перемещать вперед, если он уже находится на пути без удвоения.
Я не могу говорить о других дистрибутивах, но в Ubuntu есть файл / etc / environment, который является поиском по умолчанию для всех пользователей. Поскольку мой компьютер используется только мной, я помещаю туда любые каталоги, которые мне нужны, если только это не временное дополнение, которое я помещаю в сценарий.
В некоторых ситуациях использование PATH = / a / b: $ PATH
можно считать «неправильным» способом добавления пути к PATH
:
PATH
в той же форме.PATH
, в другой форме (т.е.псевдоним из-за использования символических ссылок или ..
).PATH
, когда он предназначен для переопределения других записей в PATH
.Эта (только для файлов) функция выполняет «правильные действия» в вышеуказанных ситуациях (за исключением, см. Ниже), возвращает коды ошибок и печатает хорошие сообщения для людей. Коды ошибок и сообщения могут быть отключены, когда они не нужны.
prepath() {
local usage="\
Usage: prepath [-f] [-n] [-q] DIR
-f Force dir to front of path even if already in path
-n Nonexistent dirs do not return error status
-q Quiet mode"
local tofront=false errcode=1 qecho=echo
while true; do case "$1" in
-f) tofront=true; shift;;
-n) errcode=0; shift;;
-q) qecho=':'; shift;;
*) break;;
esac; done
# Bad params always produce message and error code
[[ -z $1 ]] && { echo 1>&2 "$usage"; return 1; }
[[ -d $1 ]] || { $qecho 1>&2 "$1 is not a directory."; return $errcode; }
dir="$(command cd "$1"; pwd -P)"
if [[ :$PATH: =~ :$dir: ]]; then
$tofront || { $qecho 1>&2 "$dir already in path."; return 0; }
PATH="${PATH#$dir:}" # remove if at start
PATH="${PATH%:$dir}" # remove if at end
PATH="${PATH//:$dir:/:}" # remove if in middle
fi
PATH="$dir:$PATH"
}
Исключение составляет то, что эта функция не канонизирует пути, добавленные в PATH
другими способами, поэтому, если неканонический псевдоним для пути находится в PATH
, это добавит дубликат. Попытка канонизировать пути, уже находящиеся в PATH
, является рискованным предложением, поскольку относительный путь имеет очевидное значение при передаче в prepath
, но когда он уже находится в пути, вы не знаете, каким был текущий рабочий каталог при его добавлении.
Для меня (на Mac OS X 10.9.5) добавление имени пути (например,. / mypathname
) в файл / etc / paths
работал очень хорошо.
Перед редактированием echo $ PATH
возвращает:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
После редактирования / etc / paths
и перезапуска оболочки переменная $ PATH добавляется с / pathname
. Действительно, echo $ PATH
возвращается:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname
Случилось так, что / mypathname
был добавлен к переменной $ PATH
.
Вот мое решение:
PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")
Хороший легкий лайнер, который не оставляет трейлинг :
Чтобы добавить новый путь к переменной среды PATH
:
export PATH=$PATH:/new-path/
Чтобы это изменение было применено к каждой открываемой оболочке, добавьте его в файл, который оболочка будет source при вызове. В разных оболочках это может быть:
например.
# export PATH=$PATH:/root/learning/bin/
# source ~/.bashrc
# echo $PATH
Вы можете увидеть указанный путь в приведенном выше выводе.