Как правильно добавить путь к PATH?

Мне интересно, где новый путь должен быть добавлен к переменной среды PATH. Я знаю, что это можно сделать, отредактировав .bashrc (например), но неясно, как это сделать.

Сюда:

& Лт;!- язык: bash - >

export PATH=~/opt/bin:$PATH

или это?

export PATH=$PATH:~/opt/bin
Комментарии к вопросу (5)
Решение

Простые вещи

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

В bash, ksh и zsh export является специальным синтаксисом, и оба PATH = ~ / opt / bin: $ PATH и export PATH = ~ / opt / bin: $ PATH делают правильные вещи даже. В других оболочках в стиле Bourne / POSIX, таких как dash (который во многих системах называется / bin / sh), export анализируется как обычная команда, что подразумевает два различия:

Таким образом, в оболочках, таких как тире, < 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 >

Комментарии (3)

В любом случае работает, но они не делают то же самое: элементы PATH проверяются слева направо. В вашем первом примере исполняемые файлы в ~ / opt / bin будут иметь приоритет над установленными, например, в / usr / bin, которые могут быть или не быть тем, что вы хотите.

В частности, с точки зрения безопасности, опасно добавлять пути вперед, потому что, если кто-то может получить доступ для записи к вашему ~ / opt / bin, он может поместить, например, другое ls в там, который вы бы тогда использовали вместо / bin / ls, не замечая. Теперь представьте то же самое для ssh или вашего браузера или выбора... (То же самое касается тройного размещения . на вашем пути.)

Комментарии (2)

Меня смущает вопрос 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)

Пуленепробиваемый способ добавления / оценки

Есть много соображений, связанных с выбором добавления и добавления. Многие из них покрыты другими ответами, поэтому я не буду повторять их здесь.

Важным моментом является то, что, даже если системные сценарии не используют это (интересно, почему) * 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}:}расширяется до:

  1. ничего, если PATH является нулевым или неустановленным
  2. $ {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}}
...
Комментарии (0)

Linux определяет путь поиска исполняемого файла с помощью переменной среды $ PATH. Чтобы добавить каталог / data / myscripts в начало переменной среды $ PATH, используйте следующее:

PATH=/data/myscripts:$PATH

Чтобы добавить этот каталог в конец пути, используйте следующую команду:

PATH=$PATH:/data/myscripts

Но предшествующего недостаточно, потому что когда вы устанавливаете переменную среды внутри скрипта, это изменение эффективно только внутри скрипта. Есть только два способа обойти это ограничение:

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

Примеры:

$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 >

Комментарии (0)

В течение некоторого времени я держал при себе две функции 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

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

Комментарии (1)

Я не могу говорить о других дистрибутивах, но в Ubuntu есть файл / etc / environment, который является поиском по умолчанию для всех пользователей. Поскольку мой компьютер используется только мной, я помещаю туда любые каталоги, которые мне нужны, если только это не временное дополнение, которое я помещаю в сценарий.

Комментарии (0)

В некоторых ситуациях использование PATH = / a / b: $ PATH можно считать «неправильным» способом добавления пути к PATH:

  1. Добавление пути, который на самом деле не является каталогом.
  2. Добавление пути, который уже находится в PATH в той же форме.
  3. Добавление относительного пути (поскольку фактический поиск каталога изменится при изменении текущего рабочего каталога).
  4. Добавление пути, который уже находится в PATH, в другой форме (т.е.псевдоним из-за использования символических ссылок или ..).
  5. Если вы избегаете делать 4, не перемещайте путь вперед к 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, но когда он уже находится в пути, вы не знаете, каким был текущий рабочий каталог при его добавлении.

Комментарии (2)

Для меня (на 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.

Комментарии (1)

Вот мое решение:

PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")

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

Комментарии (2)

Чтобы добавить новый путь к переменной среды PATH:

export PATH=$PATH:/new-path/

Чтобы это изменение было применено к каждой открываемой оболочке, добавьте его в файл, который оболочка будет source при вызове. В разных оболочках это может быть:

  • Bash Shell: ~/.bash_profile, ~/.bashrc или профиль
  • Korn Shell: ~/.kshrc или .profile
  • Z Shell: ~/.zshrc или .zprofile

например.

# export PATH=$PATH:/root/learning/bin/
# source ~/.bashrc
# echo $PATH

Вы можете увидеть указанный путь в приведенном выше выводе.

Комментарии (0)