Как мне манипулировать элементами $ PATH в сценариях оболочки? - PullRequest
29 голосов
/ 08 ноября 2008

Есть ли идиоматический способ удаления элементов из PATH-подобных переменных оболочки?

То есть я хочу взять

PATH=/home/joe/bin:/usr/local/bin:/usr/bin:/bin:/path/to/app/bin:.

и удалить или заменить /path/to/app/bin без заусеницы остальной переменной. Дополнительные очки за то, что я могу поставить новые элементы в произвольные позиции. Цель будет распознаваема по четко определенной строке и может появиться в любой точке списка.

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

Я использую bash, но пример приветствуется и в вашей любимой оболочке.


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


Это связано с проблемой предотвращения повторяющихся элементов $PATH при повторном запуске сценариев входа в систему и т. П.


Ответы [ 12 ]

0 голосов
/ 09 сентября 2014

В соответствии с ответом dj_segfault , я делаю это в скриптах, которые добавляют / дописывают переменные среды, которые могут выполняться несколько раз:

ld_library_path=${ORACLE_HOME}/lib
LD_LIBRARY_PATH=${LD_LIBRARY_PATH//${ld_library_path}?(:)/}
export LD_LIBRARY_PATH=${ld_library_path}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

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

0 голосов
/ 08 ноября 2008

Первое, что приходит мне в голову, чтобы заменить только часть строки, это подстановка sed.

Пример: if echo $ PATH => "/ usr / pkg / bin: / usr / bin: / bin: / usr / pkg / games: / usr / pkg / X11R6 / bin" затем изменить "/ usr / bin" на "/ usr / local / bin" можно следующим образом:

## создает стандартный выходной файл

## символ "=" используется вместо косой черты ("/"), так как это было бы грязно, # альтернативный символ цитирования должен быть маловероятным в PATH

## здесь символ разделителя пути ":" удаляется и снова добавляется, # может потребоваться дополнительное двоеточие после последнего пути

echo $ PATH | sed '= / usr / bin: = / usr / local / bin: ='

Это решение заменяет весь элемент пути, поэтому может быть избыточным, если новый элемент похож.

Если новые PATH не являются динамическими, но всегда находятся в некотором постоянном наборе, вы можете сохранить эти в переменной и назначить при необходимости:

PATH = $ TEMP_PATH_1; # команды ...; \ п PATH = $ TEMP_PATH_2; # команды и т.д ...;

Может не быть тем, о чем ты думал. Вот некоторые из соответствующих команд в bash / unix:

Pushd POPD CD ls # может быть l -1A для одного столбца; находить Grep который # мог бы подтвердить, что этот файл - то, откуда, по вашему мнению, он пришел; окр тип

.. и все это и многое другое имеют некоторые отношение к PATH или каталогам в целом. Часть изменения текста может быть выполнена любым количеством способов!

Какое бы решение ни было выбрано, оно будет иметь 4 части:

1) получить путь как есть 2) декодировать путь, чтобы найти часть, нуждающуюся в изменениях 3) определение необходимых изменений / интеграция этих изменений 4) проверка / окончательная интеграция / установка переменной

...