Видаліть зайві шляхи зі змінної $ PATH


125

Я визначив той самий шлях у змінній $ PATH 6 разів.

Я не виходив, щоб перевірити, чи працює він.

Як я можу видалити дублікати?

Змінна $ PATH виглядає приблизно так:

echo $PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin

Як би я його скинув до просто

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

де ви це визначили 6 разів? в яких файлах?
hovanessyan


Відповіді:


122

Ви просто виконуєте:

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

це буде для поточного сеансу, якщо ви хочете постійно змінити, додайте його до будь-якого .bashrc, bash.bashrc, / etc / profile - все, що відповідає вашій системі та потребам користувача.

Примітка. Це для Linux. Ми зробимо це зрозумілим для нових кодерів. (`, ') Не намагайтеся встановити = ці.


так, я встановлюю їх постійно в bash.bashrc. Тож чи має бути команда щось подібне? echo 'export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games' >> ~/.bashrc
charles hendry

річ у тому, що залежно від вашої ОС виконується ланцюг конфігурацій. Вам потрібно переконатися, що змінна PATH не буде перезаписана пізніше. Найпростіший спосіб зробити це (для одного користувача) - це перезаписати його в особистий .bashrc користувача, який зазвичай знаходиться у його домашньому каталозі.
гованессян

1
ваша команда встановлює PATH на - $ PATH (поточне значення PATH) + рядок / usr / local / sbin: / usr / local / bin: / usr / sbin: / usr / bin: / sbin: / bin: / usr / gams. Якщо ви хочете мати лише рядок, видаліть зі своєї команди $ PATH + крапку з комою (:). Не має значення, використовуєте ви ехо або редагуєте файл ~ / .bashrc вручну.
hovanessyan

файл bash.bashrc знаходиться в папці / etc. Він не відображає змінну $ PATH, тому я не знаю, де її відредагувати
Чарлз Хендрі

у першому коментарі ви лунаєте до ~ / .bashrc (цитуючи: >> ~ / .bashrc), а не на /etc/bash.bashrc. Якщо ви хочете змінити PATH для конкретного користувача, відредагуйте його у файлі / home / <ім'я користувача> /. Bashrc. /etc/bash.bashrc застосовується до всіх користувачів.
hovanessyan

70

Якщо ви використовуєте Bash, ви також можете зробити наступне, якщо, скажімо, ви хочете видалити каталог /home/wrong/dir/зі PATHзмінної:

PATH=`echo $PATH | sed -e 's/:\/home\/wrong\/dir\/$//'`

1
Це було корисно для мене, оскільки в / etc / profile було додано каталог, який я хотів виключити, але не маю доступу для запису до / etc. Дякую :)
Саміздіс

13
Підказка: ви можете використовувати різний роздільник у виразі sed, щоб уникнути \ / втечі:PATH=$(echo $PATH | sed -e 's|:/home/wrong/dir|$||')
iNecas

4
Цей трюк допомагає, коли я хочу отримати новий PATH відразу, і не хочу виходити з поточного терміналу. Однак, щоб уникнути плутанини, слід експериментувати з командою, що генерує PATH (тобто echo $PATH | sed -e 's/:\/home\/wrong\/dir\/$//'), перш ніж призначити її PATH.
biocyberman

2
Це не спрацює, якщо шлях, який потрібно видалити, стане першим шляхом у $PATH. Скористайтеся цим:PATH=$(echo :$PATH: | sed -e 's,:/home/wrong/dir:,:,g' -e 's/^://' -e 's/:$//')
Робін Хсу,

не працювало $ PATH=ехо $ PATH | sed -e 's /: \ / scratch \ / sjn \ / anaconda \ / bin \ / python \ / $ //' `` для видалення / scratch / sjn / anaconda / bin / python
Mona Jalal

13

Linux: Видаліть зайві шляхи зі змінної $ PATH

Linux From Scratch має цю функцію в / etc / profile

# Functions to help us manage paths.  Second argument is the name of the
# path variable to be modified (default: PATH)
pathremove () {
        local IFS=':'
        local NEWPATH
        local DIR
        local PATHVARIABLE=${2:-PATH}
        for DIR in ${!PATHVARIABLE} ; do
                if [ "$DIR" != "$1" ] ; then
                  NEWPATH=${NEWPATH:+$NEWPATH:}$DIR
                fi
        done
        export $PATHVARIABLE="$NEWPATH"
}

Це призначено для використання з цими функціями для додавання до шляху, щоб ви не робили це зайво:

pathprepend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="$1${!PATHVARIABLE:+:${!PATHVARIABLE}}"
}

pathappend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="${!PATHVARIABLE:+${!PATHVARIABLE}:}$1"
}

Просте використання - просто дати pathremoveшлях до каталогу до видалення - але пам’ятайте, що він повинен точно відповідати:

$ pathremove /home/username/anaconda3/bin

Це видалить кожен екземпляр цього каталогу зі свого шляху.

Якщо ви хочете, щоб каталог на вашому шляху, але без надмірностей, ви можете просто використовувати одну з інших функцій, наприклад - для вашого конкретного випадку:

$ pathprepend /usr/local/sbin
$ pathappend /usr/local/bin
$ pathappend /usr/sbin
$ pathappend /usr/bin
$ pathappend /sbin
$ pathappend /bin
$ pathappend /usr/games

Але, якщо читання не викликає занепокоєння, у цей момент вам краще просто робити:

$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Чи буде вищезазначене працювати у всіх відомих людині оболонках?

Я вважаю , вище , щоб працювати в sh, dashі , по bashкрайней мере. Я був би здивований, дізнавшись, що це не працює csh, fish', orкш. Я сумніваюся, що він буде працювати в командній оболонці Windows або в Powershell.

Якщо у вас є Python, наступна команда повинна виконувати те, що прямо запитується (тобто видалити зайві шляхи):

$ PATH=$( python -c "
import os
path = os.environ['PATH'].split(':')
print(':'.join(sorted(set(path), key=path.index)))
" )

Однолінійний (для переходу до рядкових питань):

$ PATH=$( python -c "import os; path = os.environ['PATH'].split(':'); print(':'.join(sorted(set(path), key=path.index)))" )

Сказане видаляє пізніші надлишкові шляхи. Щоб видалити попередні надлишкові шляхи, використовуйте перевернутий індекс списку та знову поверніть його:

$ PATH=$( python -c "
import os
path = os.environ['PATH'].split(':')[::-1]
print(':'.join(sorted(set(path), key=path.index, reverse=True)))
" )

+1. чи працює pathremove () у будь-яких смаках оболонок, наприклад, csh, ksh, bash тощо? btw, мій / etc / профіль у RHEL не має partremove (), а має лише pathmunge ().
Тагар

1
@Tagar Я не даю жодних гарантій щодо сумісності з усіма іншими оболонками. Я пропоную протестувати його на будь-якій оболонці, яку ви використовуєте, і якщо вона не працює для вашої оболонки, ви можете використовувати Python, якщо у вас її встановлено - я додав трохи відповіді Python, щоб описати, як.
Аарон Холл

Якщо я прочитав "3.5.3 Розширення параметра оболонки" правильно, ${!PATHVARIABLE}це своєрідна змінна непрямість, але я не впевнений, як це працює тут. Не могли б ви пояснити, будь ласка?
loxaxs

@loxaxs Це локальна змінна в цих функціях bash, оголошених localвбудованим (який можна використовувати лише всередині функції.) Якщо у вас є додаткові запитання, вам, ймовірно, слід задати нове запитання на сайті (після того, як шукати його спочатку, щоб переконатися ви не створюєте точний дублікат ...).
Аарон Холл

Це дійсно цікава відповідь, дякую за написання! Однак, оригінальне питання очищення змішаної змінної PATH, здається, не вирішується елегантно (але, зізнаюся, тоді при використанні цих функцій не можна було б почати з заплутаним PATH для початку).
Крістіан Геренц

9

Ось один код рядка, який очищає ПАТ

  • Це не порушує порядок PATH, просто видаляє дублікати
  • Лікує: і виправдовує ПАРТ витончено
  • Не використовуються спеціальні символи, тому не потрібно втечі
  • Використовує /bin/awkтак, що це працює навіть при порушенні PATH

    export PATH="$(echo "$PATH" |/bin/awk 'BEGIN{RS=":";}
    {sub(sprintf("%c$",10),"");if(A[$0]){}else{A[$0]=1;
    printf(((NR==1)?"":":")$0)}}')";
    

1
хтось це перевіряв? безпечно?
Джо РР

2
якщо у вас не встановлено awk, він очищає ваш шлях, раджу скопіювати свій шлях до файлу txt раніше, ніж з echo $ PATH
Хосе Піта

Не працює для мене ... У мене встановлено awk, але деякі копії не видаляються.
Крістіан Херенц

3
  1. Просто echo $PATH
  2. скопіюйте деталі в текстовий редактор
  3. видалити небажані записи
  4. PATH= # pass new list of entries

2

Якщо ви просто хочете видалити будь-які повторювані контури, я використовую цей сценарій, який я написав деякий час назад, оскільки у мене виникли проблеми з кількома шляхами perl5 / bin:

#!/bin/bash
#
# path-cleanup
#
# This must be run as "source path-cleanup" or ". path-cleanup"
# so the current shell gets the changes.

pathlist=`echo $PATH | sed 's/:/\n/g' | uniq`

# echo "Starting PATH: $PATH"
# echo "pathlist: $pathlist"
unset PATH
# echo "After unset, PATH: $PATH"
for dir in $pathlist
do
    if test -d $dir ; then
        if test -z $PATH; then
            PATH=$dir
        else
            PATH=$PATH:$dir
        fi
    fi
done
export PATH
# echo "After loop, PATH: $PATH"

І я помістив його у своєму ~ / .profile наприкінці. Оскільки я використовую BASH майже виключно, я не пробував його в інших оболонках.


1
+1 для рішення. Btw, він видалить контури дублювання лише у тому випадку, якщо вони збираються в списку один за одним. Ви можете змінити, |uniqщоб |sort|uniqвиправити це, але це змінить порядок усіх каталогів на шляху, який, на мою думку, не є бажаним побічним ефектом.
Тагар

1

Якщо припустити, що ваша оболонка - Bash, ви можете встановити шлях

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

але як сказав Левон в іншій відповіді, як тільки ви скасуєте оболонку, зміни не зникнуть. Ви , ймовірно , хочете створити свій PATHін ~/.bash_profileабо ~/.bashrc.


1

У bash ви просто можете $ {var / find / substitution}

PATH=${PATH/%:\/home\/wrong\/dir\//}

Або в цьому випадку (оскільки біт заміни порожній) просто:

PATH=${PATH%:\/home\/wrong\/dir\/}

Я прийшов сюди першим, але пішов на інший посуд, тому що я думав, що для цього буде розширення параметрів . Легше, ніж sed !.

Як замінити символ або слово заповнювача в змінній на значення з іншої змінної в Bash?


%означає відповідність, якщо в кінці рядка #є для початку.
сабгентон

0

Немає стандартних інструментів для "редагування" значення $PATH(тобто "додавання папки лише тоді, коли її вже немає" або "видалення цієї папки").

Щоб перевірити, яким був би шлях під час наступного входу, використовуйте telnet localhost(або telnet 127.0.0.1). Потім він запитає ваше ім’я користувача та пароль.

Це дає вам нову оболонку входу (тобто абсолютно нову, яка нічого не успадковує з поточного середовища).

Ви можете перевірити значення $PATHтам і відредагувати файли rc, поки воно не буде правильним. Це також корисно, щоб дізнатися, чи можна взагалі знову входити після зміни змін на важливий файл.


Замість того, щоб вводити ім’я користувача / пароль, просто введіть /bin/bash -i. Набагато менше клопоту.
Ed Heal

0

Як ви додали ці дублікати шляхів до змінної PATH? Ви, мабуть, відредагували один із своїх .файлів. ( .tcshrcабо .bashrcтощо, залежно від конкретної системи / оболонки). Спосіб виправити це - знову відредагувати файл та видалити повторювані контури.

Якщо ви не редагували жодні файли, і ви, мабуть, інтерактивно змінили PATH. У такому випадку зміни не "пристануть", тобто якщо ви відкриєте іншу оболонку, або вийдете та увійдете назад, зміни будуть відключені автоматично.

Зауважте, що існують і деякі конфігураційні файли для всієї системи, але навряд чи ви їх змінили, тому, швидше за все, ви будете змінювати файли в особистому домашньому каталозі (якщо ви хочете зробити ці зміни постійними, як тільки ви встановите набір шляхів)


0

Для простого копіювання та вставки шаблону я використовую цей фрагмент Perl:

PATH=`echo $PATH | perl -pe s:/path/to/be/excluded::`

Таким чином, вам не потрібно уникати косої риски оператора-замінника.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.