Я хотел бы добавить что-то в $ PATH, для всей системы или для отдельного пользователя, без потенциального добавления одного и того же пути несколько раз.
Одна из причин, по которой нужно это сделать, заключается в том, что можно добавлять дополнения .bashrc
, которые не требуют входа в систему, а также более полезны в системах, которые используют (например) lightdm
, которые никогда не звонят .profile
.
Мне известны вопросы о том, как удалить дубликаты из $ PATH, но я не хочу удалять дубликаты . Я хотел бы, чтобы способ добавить пути, только если они еще не присутствуют.
Ответы:
Предположим, что новый путь, который мы хотим добавить:
Затем, используя любую оболочку POSIX, мы можем проверить, есть ли
new
уже путь, и добавить его, если его нет:Обратите внимание на использование двоеточий. Без двоеточий, мы могли бы подумать, что, скажем,
new=/bin
уже был на пути, потому что это образец соответствовал/usr/bin
. Хотя PATH обычно имеют много элементов, особые случаи нуля и одного элемента в PATH также обрабатываются. Случай PATH, изначально не имеющий элементов (будучи пустым), обрабатывается с помощью${PATH:=$new}
которого присваиваетсяPATH
значение,$new
если оно пустое. Установка значений по умолчанию для параметров таким способом является свойством всех оболочек POSIX: см. Раздел 2.6.2 документации по POSIX .)Вызываемая функция
Для удобства приведенный выше код можно поместить в функцию. Эту функцию можно определить в командной строке или, чтобы она была доступна постоянно, добавить в скрипт инициализации вашей оболочки (для пользователей bash это будет так
~/.bashrc
):Чтобы использовать эту функцию обновления пути для добавления каталога в текущий PATH:
источник
PATH
пусто, это добавит пустую запись (т.е. текущий каталог) вPATH
. Я думаю, что вам нужен еще один случай.case
. Просто делайcase "${PATH:=$new}"
. Смотрите мой собственный ответ для аналогичных откатов.Создайте файл в
/etc/profile.d
вызываемой, например,mypath.sh
(или как вы хотите). Если вы используете lightdm, убедитесь, что он жизнеспособен или используется,/etc/bashrc
или файл получен из него. Добавьте к этому следующие функции:Вещи в начале (с добавлением) $ PATH имеют приоритет перед тем, что следует, и наоборот, вещи в конце (с добавлением) будут заменены тем, что предшествует. Это означает, что если ваш $ PATH есть
/usr/local/bin:/usr/bin
иgotcha
в обоих каталогах есть исполняемый файл,/usr/local/bin
по умолчанию будет использоваться тот, который в.Теперь вы можете - в этом же файле, в другом файле конфигурации оболочки или из командной строки - использовать:
Если это в a
.bashrc
, это предотвратит появление значения более одного раза при запуске новой оболочки. Есть ограничение в том, что если вы хотите добавить что-то, что было добавлено (то есть переместить путь в $ PATH) или наоборот, вам придется сделать это самостоятельно.источник
$PATH
сIFS=:
в конечном итоге является более гибким, чемcase
.case
, IMO. Я полагаю,awk
что здесь тоже можно найти хорошее применение.gawk
мог напрямую назначить$PATH
.Вы можете сделать это следующим образом:
Примечание: если вы строите PATH из других переменных, убедитесь, что они не пусты, для многих оболочек интерпретируйте «как». ,
источник
-q
POSIX требуется для grep, но я не знаю, означает ли это, что есть еще некоторые (не POSIX) greps, у которых ее нет./my/bin
Важной частью кода является проверка,
PATH
содержит ли конкретный путь:То есть, убедитесь, что каждый путь в
PATH
разделен с обеих сторонPATH
разделителем (:
), затем проверьте (-q
), существует ли там литеральная строка (-F
), состоящая изPATH
разделителя, вашего пути и другогоPATH
разделителя. Если это не так, вы можете безопасно добавить путь:Это должно быть POSIX-совместимым и должно работать с любым путем, не содержащим символ новой строки. Это более сложно, если вы хотите, чтобы он работал с путями, содержащими символ новой строки, будучи совместимым с POSIX, но если у вас есть,
grep
который поддерживает,-z
вы можете использовать это.источник
Я нес эту маленькую функцию со мной в различных
~/.profile
файлах в течение многих лет. Я думаю, что это было написано сисадмином в лаборатории, в которой я работал, но я не уверен. В любом случае, это похоже на подход Златовласки, но немного отличается:Итак, чтобы добавить новый каталог в начало
PATH
:и до конца:
источник
/bin/grep
->grep
ОБНОВИТЬ:
Я заметил, что у вашего собственного ответа была отдельная функция для добавления или добавления к
$PATH
. Мне понравилась идея. Поэтому я добавил немного обработки аргументов. Я также правильно_
назвал это:ВЫХОД:
По умолчанию это будет
-A
зависеть от$PATH
, но вы можете изменить это поведение, чтобы-P
повторить, добавив-P
любое место в вашем списке аргументов. Вы можете переключить его обратно в-A
режим ожидания, передав его-A
снова.БЕЗОПАСНОЕ EVAL
В большинстве случаев я рекомендую людям избегать любого использования
eval
. Но это, я думаю, выделяется как пример его использования насовсем. В этом случае единственное утверждение, котороеeval
можно увидеть, этоP=
илиA=
. Значения его аргументов строго проверяются до того, как он будет вызван. Это для чегоeval
.Это примет столько аргументов, сколько вы дадите, и добавите каждый из них
$PATH
только один раз и только если его еще нет$PATH
. Он использует только полностью переносимый POSIX-скрипт оболочки, опирается только на встроенные функции оболочки и очень быстр.источник
_
префиксные функции оболочки делают их «должным образом распределенными по пространству имен»? В других языках обычно указывается внутренняя глобальная функция (то есть та, которая должна быть глобальной, но не предназначена для внешнего использования как часть API). Мои имена, конечно, не_
лучший выбор, но мне кажется, что простое использование не решает проблемы коллизий вообще - было бы лучше использовать собственное пространство имен, например.mikeserv_path_assign()
,_
вам нужно переключить менеджеры пакетов. В любом случае, это, по сути, просто «глобальная, внутренняя функция» - она глобальна для каждой оболочки, вызванной из оболочки, в которой она объявлена, и это лишь небольшая часть интерпретируемого языкового скрипта, висящая в памяти интерпретатора. , unix.stackexchange.com/questions/120528/…unset a
(или эквивалент) в конце профиля?Вот! Индустриальная мощная 12-строчная ... техническая bash- и zsh-переносимая функция оболочки, которая преданно любит ваш
~/.bashrc
или~/.zshrc
запускаемый скрипт:Приготовься к мгновенной славе. Тогда, вместо того чтобы делать это и желать надежды на лучшее:
Сделайте это вместо этого и будьте уверены, что получите лучшее, действительно ли вы этого хотели или нет:
Отлично, определите «лучший».
Безопасное добавление и добавление к току
${PATH}
не является обычным делом. В то время как удобные и кажущиеся разумными, однострочники формыexport PATH=$PATH:~/opt/bin
вызывают дьявольские осложнения с:Случайно относительные dirnames (например,
export PATH=$PATH:opt/bin
). Хотя в большинстве случаевbash
иzsh
безмолвно принимают и в основном игнорируют относительные имена dirname , относительные имена dirnames с префиксом либо или (и, возможно, других гнусных персонажей) заставляют обоих позорно изуродовать себя оригинальным шедевром аля Масаки Кобаяши 1962 года Харакири :h
t
Случайно дублируйте имена. Хотя дубликаты
${PATH}
каталогов в основном безвредны, они также нежелательны, громоздки, слегка неэффективны, затрудняют отладку и способствуют износу дисков - как этот ответ. Хотя твердотельные накопители в стиле NAND ( конечно ) не подвержены износу при чтении, жесткие диски - нет. Ненужный доступ к файловой системе при каждой попытке команды подразумевает ненужный износ считывающей головки в одном и том же темпе. Дубликаты особенно неуместны, когда вызывают вложенные оболочки в вложенных подпроцессах, и в этот момент кажущиеся безобидными однострочникиexport PATH=$PATH:~/wat
быстро взрываются, как Седьмой круг${PATH}
адаPATH=/usr/local/bin:/usr/bin:/bin:/home/leycec/wat:/home/leycec/wat:/home/leycec/wat:/home/leycec/wat
. Только Вельзевул может помочь вам, если вы добавите к этому дополнительные имена. (Не позволяй этому случиться с твоими драгоценными детьми. )${PATH}
имена каталогов в основном безвредны, они также обычно нежелательны, громоздки, слегка неэффективны, препятствуют отладке и способствуют износу дисков.Ergo, дружественная автоматизация, подобная функции оболочки, определенной выше. Мы должны спасти себя от самих себя.
Но ... Почему "+ path.append ()"? Почему не просто append_path ()?
Для disambiguity (например, с внешними командами в текущей
${PATH}
или всей системе функций оболочки , определенных в другом месте), определяемого пользователь функция оболочки идеально приставка или суффикс с уникальными подстроками , поддерживаемыхbash
и ,zsh
но иным образом запрещена для стандартных команд basenames - как, скажем,+
.Привет. Оно работает. Не суди меня.
Но ... Почему "+ path.append ()"? Почему бы не "+ path.prepend ()"?
Поскольку присоединение к току
${PATH}
безопаснее, чем присоединение к току${PATH}
, все вещи равны, а они никогда не равны. Переопределение общесистемных команд пользовательскими командами в лучшем случае может быть антисанитарным, а в худшем - безумным. Например, в Linux нижестоящие приложения обычно ожидают варианты команд GNU coreutils, а не нестандартные нестандартные производные или альтернативы.Тем не менее, есть абсолютно допустимые варианты использования для этого. Определение эквивалентной
+path.prepend()
функции тривиально. Sans prolix nebulosity, для его и ее общего здравомыслия:Но ... Почему не Жиль?
Жиля ' приемлемого ответа в другом месте выразительно оптимальный в общем случае в виде „оболочка агностического идемпотентного Append“ . Однако в обычном случае
bash
иzsh
при отсутствии нежелательных символических ссылок потеря производительности, требуемая для этого, огорчает меня в Gentoo . Даже при наличии нежелательных симлинок, это спорно ли разветвление один подоболочки вadd_to_PATH()
аргумент стоит потенциала вставки символических ссылок дублей.Для строгих случаев использования, требующих устранения даже дубликатов символических ссылок, этот
zsh
-специфичный вариант делает это с помощью эффективных встроенных функций, а не неэффективных вилок:Обратите внимание,
*":${dirname:A}:"*
а не*":${dirname}:"*
оригинал.:A
Удивительныйzsh
-изм, к сожалению, отсутствует в большинстве других оболочек - в том числеbash
. Цитироватьman zshexpn
:Больше нет вопросов.
Пожалуйста. Наслаждайтесь безопасным обстрелом. Теперь вы это заслужили.
источник
Вот моя версия в стиле функционального программирования.
*PATH
переменной, разделенной двоеточиями , не толькоPATH
.Также стоит отметить:
export
ИГ; это остается для звонящего (см. примеры)bash
; нет разветвленияисточник
Этот скрипт позволяет добавить в конце
$PATH
:Или добавить в начале
$PATH
:источник