Или, в более общем плане, как мне удалить элемент из списка, разделенного двоеточиями, в переменной среды Bash?
Я думал, что видел простой способ сделать это много лет назад, используя более продвинутые формы расширения переменных Bash, но в таком случае я потерял его из виду. Быстрый поиск в Google дал на удивление мало релевантных результатов, и ни один из них я бы не назвал «простым» или «элегантным». Например, два метода с использованием sed и awk соответственно:
PATH=$(echo $PATH | sed -e 's;:\?/home/user/bin;;' -e 's;/home/user/bin:\?;;')
PATH=!(awk -F: '{for(i=1;i<=NF;i++){if(!($i in a)){a[$i];printf s$i;s=":"}}}'<<<$PATH)
Нет ничего простого? Есть ли что-нибудь аналогичное функции split () в Bash?
Обновление:
похоже, мне нужно извиниться за мой намеренно расплывчатый вопрос; Меня меньше интересовало решение конкретного варианта использования, чем спровоцировать хорошее обсуждение. К счастью, я понял!
Здесь есть несколько очень умных приемов. В конце концов, я добавил в свой набор инструментов следующие три функции. Магия происходит в path_remove, который во многом основан на умном использовании Мартином Йорком awk
переменной RS.
path_append () { path_remove $1; export PATH="$PATH:$1"; }
path_prepend () { path_remove $1; export PATH="$1:$PATH"; }
path_remove () { export PATH=`echo -n $PATH | awk -v RS=: -v ORS=: '$0 != "'$1'"' | sed 's/:$//'`; }
Единственная реальная проблема здесь - это использование sed
для удаления конечной двоеточия. Однако, учитывая, насколько проста остальная часть решения Мартина, я вполне готов смириться с этим!
Связанный вопрос: Как управлять элементами $ PATH в сценариях оболочки?
источник
WORK=`echo -n ${1} | awk -v RS=: -v ORS=: '$0 != "'${3}'"' | sed 's/:$//'`; eval "export ${2}=${WORK}"
но вы должны называть ееfunc $VAR VAR pattern
(на основе @ martin-york и @ andrew-aylett)Ответы:
Минута с awk:
Изменить: это ответ на комментарии ниже:
Изменить в ответ на проблему безопасности: (это не имеет отношения к вопросу)
Это удалит все оставшиеся конечные двоеточия, удалив последние записи, которые фактически добавят
.
к вашему пути.источник
PATH
переменных делает , как специальное правило, обозначает текущий каталог всех оболочек Unix , так как , по крайней мере V7 Unix в 1979 году он все еще вbash
. Проверьте руководство или попробуйте сами.Мой грязный хак:
источник
Поскольку большая проблема с заменой - это конечные варианты, как насчет того, чтобы конечные варианты не отличались от других вариантов? Если бы путь уже имел двоеточия в начале и в конце, мы могли бы просто искать нужную строку, заключенную в двоеточия. Как бы то ни было, мы можем легко добавить эти двоеточия и впоследствии удалить их.
Чистый баш :).
источник
WORK
иPATH
поскольку расширение переменной происходит после того, как строка разбита на разделы для назначения переменных и выполнения команд.REMOVE
может потребоваться заключить в кавычки, или вы можете просто вставить свою строку прямо в замену, если это константа.Вот самое простое решение, которое я могу придумать:
В приведенном выше примере будет удален любой элемент в $ PATH, содержащий «usr». Вы можете заменить «* usr *» на «/ home / user / bin», чтобы удалить только этот элемент.
обновить за sschuberth
Хотя я считаю, что пробелы в a
$PATH
- ужасная идея, вот решение, которое справится с этим:или
источник
Вот однострочник, который, несмотря на текущие принятые и самые популярные ответы, не добавляет невидимых символов в PATH и может справиться с путями, содержащими пробелы:
Лично я также считаю, что это легко читать / понимать, и в нем используются только общие команды вместо использования awk.
источник
export PATH=$(p=$(echo $PATH | tr ":" "\0" | grep -v -z "/cygwin/" | tr "\0" ":"); echo ${p%:})
(хотя, возможно, вы можете спросить себя, зачем вам это нужно, если вы это делаете :))grep -v "^/path/to/remove\$"
илиgrep -v -x "/path/to/remove"
tr
встречается чащеawk
? ;)tr
, чем с интерпретаторомawk
.echo "..."
сprintf "%s" "..."
для того , чтобы работать над путями , как-e
и другие подобные. См. Stackoverflow.com/a/49418406/102441Вот решение, которое:
IFS
,удаляет все вхождения аргумента в
PATH
.источник
Выкопал из моего файла .bashrc. Когда вы играете с PATH, и он теряется, awk / sed / grep становится недоступным :-)
источник
Лучший вариант чистого bash, который я нашел до сих пор, следующий:
Это основано на не совсем правильном ответе на Добавить каталог в $ PATH, если его еще нет в Superuser.
источник
removePath () { PATH=${PATH/":$1"/}; PATH=${PATH/"$1:"/}; }
$PATH
содержит подпапку целевого (т.е. подлежащего удалению) пути. Например:a:abc/def/bin:b
->a/bin:b
, когдаabc/def
нужно удалить.Я только что использовал функции в дистрибутиве bash, которые, по-видимому, существуют с 1991 года. Они все еще находятся в пакете bash-docs в Fedora и использовались
/etc/profile
, но не более ...источник
Я написал ответ на это здесь (тоже используя awk). Но я не уверен, что это то, что вы ищете? По крайней мере, мне кажется ясным, что он делает, вместо того, чтобы вписываться в одну строку. Однако для простого лайнера, который удаляет только вещи, я рекомендую
Замена
или (короче, но менее читаемо)
В любом случае, по поводу того же вопроса и множества полезных ответов см. Здесь .
источник
awk '$0 !~ "/bin"'
. Т.е. оставьте строки, не содержащие '/ bin', с помощью оператора awk!~
.Что ж, в bash, поскольку он поддерживает регулярное выражение, я бы просто сделал:
источник
Мне нравятся три функции, показанные в обновлении @ BenBlank его исходного вопроса. Чтобы обобщить их, я использую форму с двумя аргументами, которая позволяет мне установить PATH или любую другую переменную среды, которую я хочу:
Примеры использования:
Обратите внимание, что я также добавил несколько кавычек, чтобы обеспечить правильную обработку имен путей, содержащих пробелы.
источник
Что может быть элегантнее awk?
Python! Это более удобочитаемое и удобное в обслуживании решение, и его легко проверить, чтобы убедиться, что оно действительно делает то, что вы хотите.
Скажем, вы хотите удалить первый элемент пути?
(Вместо того
echo
,os.getenv['PATH']
чтобы передавать по конвейеру из , было бы немного короче и обеспечивало бы тот же результат, что и выше, но я беспокоюсь, что Python может что-то сделать с этой переменной среды, поэтому, вероятно, лучше всего передать его напрямую из среды, которая вам небезразлична. .)Аналогично удалить с конца:
Чтобы сделать эти многоразовые функции оболочки, которые вы можете, например, вставить в свой файл .bashrc:
источник
Да, например, если поставить двоеточие в конце PATH, удаление пути станет менее неуклюжим и подверженным ошибкам.
источник
Если вас беспокоит удаление дубликатов в $ PATH, то, IMHO, самым элегантным способом было бы не добавлять их в первую очередь. В 1 строке:
$ folder можно заменить чем угодно и может содержать пробелы ("/ home / user / my documents")
источник
Самое элегантное решение на чистом bash, которое я нашел на сегодняшний день:
источник
Большинство других предложенных решений полагаться только на совпадения строк и не учитывает сегменты пути , содержащие специальные имена , как
.
,..
или~
. Приведенная ниже функция bash разрешает строки каталога в своем аргументе и в сегментах пути, чтобы найти совпадения логических каталогов, а также совпадения строк.Тест:
источник
Linux с нуля определяет три функции Bash в
/etc/profile
:Ссылка: http://www.linuxfromscratch.org/blfs/view/svn/postlfs/profile.html
источник
Я знаю, что этот вопрос касается BASH, который все должны предпочесть, но поскольку мне нравится симметрия, а иногда мне нужно использовать csh, я создал эквивалент для path_prepend (), path_append () и path_remove () "элегантное решение выше.
Суть в том, что "csh" не имеет функций, поэтому я помещаю в свой личный каталог bin небольшие сценарии оболочки, которые действуют как функции. Я создаю псевдонимы для SOURCE этих сценариев, чтобы внести изменения в назначенную переменную среды.
~ / Bin / _path_remove.csh:
~ / Bin / _path_append.csh:
~ / Bin / _path_prepend.csh:
~ / Bin / .cshrc:
Вы можете использовать их вот так ...
источник
Поскольку это имеет тенденцию быть довольно проблематичным, поскольку НЕТ элегантного способа, я рекомендую избегать проблемы, переставив решение: создайте свой PATH, а не пытайтесь его разрушить.
Я мог бы быть более конкретным, если бы знал реальный контекст вашей проблемы. А пока я буду использовать в качестве контекста сборку программного обеспечения.
Распространенная проблема со сборками программного обеспечения заключается в том, что они ломаются на некоторых машинах, в конечном итоге из-за того, как кто-то настроил свою оболочку по умолчанию (PATH и другие переменные среды). Изящное решение - сделать ваши сценарии сборки невосприимчивыми, полностью указав среду оболочки. Кодируйте свои сценарии сборки, чтобы установить PATH и другие переменные среды на основе сборки частей, которые вы контролируете, таких как расположение компилятора, библиотек, инструментов, компонентов и т. Д. Сделайте каждый настраиваемый элемент чем-то, что вы можете индивидуально настраивать, проверять и затем используйте его соответствующим образом в своем сценарии.
Например, у меня есть Java-сборка на основе Maven, ориентированная на WebLogic, которую я унаследовал от моего нового работодателя. Скрипт сборки известен своей хрупкостью, и мы с другим новым сотрудником потратили три недели (не полный рабочий день, просто кое-где, но все же много часов), заставляя его работать на наших машинах. Важным шагом было то, что я взял под свой контроль PATH, чтобы точно знать, какая Java, какая Maven и какая WebLogic вызывается. Я создал переменные среды, чтобы указать на каждый из этих инструментов, затем рассчитал PATH на основе этих и нескольких других. Подобные методы обуздали другие настраиваемые параметры, пока мы, наконец, не создали воспроизводимую сборку.
Кстати, не используйте Maven, Java в порядке, и покупайте WebLogic только в том случае, если вам абсолютно необходима его кластеризация (но в остальном нет, и особенно его проприетарные функции).
С наилучшими пожеланиями.
источник
PATH
. Конечно, вы можете создать свое собственное, но каждый раз, когда ваш администратор перемещает что-то, вам нужно выяснить, куда он это поместил. Такого рода поражение преследует цель иметь администратора.Как и в случае с @litb, я дал ответ на вопрос « Как мне манипулировать элементами $ PATH в сценариях оболочки », так что мой основной ответ там.
Функциональность «разделения» в
bash
и других производных оболочки Борна наиболее точно достигается с$IFS
помощью межполевого разделителя. Например, чтобы установить позиционные аргументы ($1
,$2
, ...) к элементам PATH, использование:Он будет работать нормально, пока в $ PATH нет пробелов. Заставить его работать для элементов пути, содержащих пробелы, - нетривиальное упражнение, оставшееся для заинтересованного читателя. Вероятно, проще справиться с этим, используя язык сценариев, такой как Perl.
У меня также есть скрипт,
clnpath
который я часто использую для установки моего PATH. Я задокументировал это в ответе на « Как не дублировать переменную PATH в csh ».источник
Что делает эту проблему раздражающей, так это случаи, когда между первым и последним элементами находятся столбики. Проблема может быть элегантно решена путем изменения IFS и использования массива, но я не знаю, как повторно ввести двоеточие после преобразования пути в форму массива.
Вот немного менее элегантная версия, которая удаляет только одну директорию с
$PATH
помощью строковых манипуляций. Я это проверил.источник
Вот однострочный Perl:
$a
Переменная получает путь , который будет удален.s
(Запасной) иprint
команда неявно действуют на$_
переменном.источник
Здесь хорошие вещи. Я использую это, чтобы не добавлять дубликаты.
источник
case ":$PATH:" in (*:"$nodup":*) ;; (*) PATH="$PATH:$nodup" ;; esac
При включенной расширенной подстановке можно делать следующее:
источник
Расширенная подстановка однострочников (ну вроде как):
Кажется, нет необходимости избегать косой черты в $ 1.
источник
Добавляя двоеточия в PATH, мы также можем сделать что-то вроде:
источник
В path_remove_all (через прокси):
источник
Хотя это очень старый поток, я подумал, что это решение может быть интересно:
нашел это в этом сообщении в блоге . Думаю, этот мне нравится больше всего :)
источник
Я использовал несколько иной подход, чем большинство людей здесь, и сосредоточился конкретно на манипуляциях со строками, например:
Выше приведен упрощенный пример последних функций, которые я использую. Я также создал
path_add_before
иpath_add_after
разрешил вам вставлять путь до / после указанного пути уже в PATH.Полный набор функций доступен в path_helpers.sh в моих точечных файлах . Они полностью поддерживают удаление / добавление / добавление / вставку в начале / середине / конце строки PATH.
источник