ลบเส้นทางที่ซ้ำซ้อนออกจากตัวแปร $ 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 เราจะแจ้งให้ชัดเจนสำหรับผู้เขียนโค้ดรายใหม่ (`, ') อย่าพยายาม SET = สิ่งเหล่านี้


ใช่ฉันตั้งค่าอย่างถาวรใน 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 ส่วนตัวของผู้ใช้ซึ่งโดยทั่วไปจะอยู่ในโฮมไดเร็กทอรีของเขา
hovanessyan

1
คำสั่งของคุณตั้งค่า PATH เป็น - $ PATH (ค่าปัจจุบันของ PATH) + สตริง / usr / local / sbin: / usr / local / bin: / usr / sbin: / usr / bin: / sbin: / bin: / usr / เกม ES หากคุณต้องการมีเพียง String ให้ลบ $ PATH + เครื่องหมายอัฒภาค (:) ออกจากคำสั่งของคุณ ไม่สำคัญว่าคุณจะใช้ echo หรือแก้ไขไฟล์ ~ / .bashrc ด้วยมือ
hovanessyan

ไฟล์ bash.bashrc อยู่ในโฟลเดอร์ / etc มันไม่แสดงตัวแปร $ PATH ดังนั้นฉันไม่แน่ใจว่าจะแก้ไขได้ที่ไหน
charles hendry

ในความคิดเห็นแรกของคุณคุณ echo ถึง ~ / .bashrc (อ้างถึง: >> ~ / .bashrc) ไม่ใช่ /etc/bash.bashrc หากคุณต้องการเปลี่ยนเส้นทางสำหรับผู้ใช้เฉพาะให้แก้ไขในไฟล์ / home / <the name of the user> /. bashrc /etc/bash.bashrc ใช้กับผู้ใช้ทั้งหมด
hovanessyan

70

หากคุณใช้ Bash คุณสามารถทำสิ่งต่อไปนี้ได้หากสมมติว่าคุณต้องการลบไดเร็กทอรี/home/wrong/dir/ออกจากPATHตัวแปรของคุณ:

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

1
สิ่งนี้มีประโยชน์สำหรับฉันเนื่องจากมีการเพิ่มไดเรกทอรีใน / etc / profile ซึ่งฉันต้องการยกเว้น แต่ไม่มีสิทธิ์เขียน / etc ขอบคุณ :)
Samizdis

13
Protip: คุณสามารถใช้ตัวคั่นที่แตกต่างกันในนิพจน์ sed เพื่อหลีกเลี่ยง \ / PATH=$(echo $PATH | sed -e 's|:/home/wrong/dir|$||')
escape

4
เคล็ดลับนี้ช่วยได้เมื่อฉันต้องการมีเส้นทางใหม่ทันทีและไม่ต้องการออกจากระบบเทอร์มินัลปัจจุบัน อย่างไรก็ตามเพื่อหลีกเลี่ยงความสับสนเราควรทดลองกับคำสั่งสร้าง PATH (เช่นecho $PATH | sed -e 's/:\/home\/wrong\/dir\/$//') ก่อนกำหนดให้กับ PATH
biocyberman

2
$PATHนี้จะไม่ทำงานเมื่อเส้นทางที่จะลบที่จะเกิดขึ้นในวันที่ 1 เส้นทาง ใช้อันนี้:PATH=$(echo :$PATH: | sed -e 's,:/home/wrong/dir:,:,g' -e 's/^://' -e 's/:$//')
Robin Hsu

ไม่ทำงาน$ 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', orksh` ฉันสงสัยว่ามันจะทำงานในเชลล์คำสั่งของ 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 / profile ของฉันบน RHEL ไม่มี partremove () แต่มี pathmunge () เท่านั้น
Tagar

1
@Tagar ฉันไม่รับประกันเกี่ยวกับความเข้ากันได้กับเปลือกหอยอื่น ๆ ทั้งหมด ฉันขอแนะนำให้ทดสอบกับเชลล์ที่คุณใช้และถ้ามันใช้ไม่ได้กับเชลล์ของคุณคุณสามารถใช้ Python ได้หากคุณติดตั้งไว้ - ฉันได้เพิ่ม Python ลงในคำตอบเพื่ออธิบายวิธีการ
แอรอนฮอลล์

ถ้าฉันอ่าน "3.5.3 Shell Parameter Expansion" อย่างถูกต้อง${!PATHVARIABLE}เป็นตัวแปรทิศทางหนึ่ง แต่ฉันไม่แน่ใจว่ามันทำงานอย่างไรที่นี่ ช่วยอธิบายหน่อยได้ไหม
loxaxs

@loxaxs นั่นคือตัวแปรท้องถิ่นในฟังก์ชัน bash เหล่านั้นซึ่งประกาศด้วยlocalbuiltin (ซึ่งสามารถใช้ได้เฉพาะในฟังก์ชันเท่านั้น) หากคุณมีคำถามเพิ่มเติมคุณควรถามคำถามใหม่ในไซต์ (หลังจากค้นหาก่อนเพื่อให้แน่ใจว่า คุณไม่ได้สร้างรายการที่ซ้ำกันแน่นอน ... )
Aaron Hall

นี่เป็นคำตอบที่น่าสนใจมากขอบคุณสำหรับการเขียน! อย่างไรก็ตามคำถามเดิมของการทำความสะอาดตัวแปร PATH ที่ยุ่งเหยิงดูเหมือนจะไม่ได้รับการแก้ไขอย่างหรูหรา (แต่ฉันยอมรับว่าเมื่อใช้ฟังก์ชันนี้จะไม่จบลงด้วยการเริ่มต้นด้วย PATH ที่ยุ่งเหยิง)
Christian Herenz

9

นี่คือรหัสบรรทัดเดียวที่ล้าง PATH

  • ไม่รบกวนลำดับของ PATH เพียงแค่ลบรายการที่ซ้ำกัน
  • ปฏิบัติต่อ: และเสริมสร้างเส้นทางอย่างสง่างาม
  • ไม่ต้องใช้อักขระพิเศษจึงไม่ต้องใช้ Escape
  • ใช้/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
ใครทดสอบบ้าง มีความปลอดภัย?
Joe RR

2
หากคุณไม่ได้ติดตั้ง awk มันจะทำความสะอาดเส้นทางของคุณฉันแนะนำให้คัดลอกเส้นทางของคุณไปยังไฟล์ txt ก่อนด้วย echo $ PATH
Jose Pita

ไม่ได้ผลสำหรับฉัน ... ฉันติดตั้ง awk แล้ว แต่บางรายการที่ซ้ำกันไม่ได้ถูกลบออก
Christian Herenz

4
  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แก้ไขปัญหานี้ แต่จะเปลี่ยนลำดับของไดเรกทอรีทั้งหมดในเส้นทางที่ฉันไม่คิดว่าเป็นผลข้างเคียงที่ต้องการ
Tagar

1

สมมติว่าเชลล์ของคุณคือ Bash คุณสามารถกำหนดเส้นทางด้วย

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

แต่เช่นเดียวกับที่ Levon กล่าวในคำตอบอื่นทันทีที่คุณยกเลิกเชลล์การเปลี่ยนแปลงจะหายไป คุณอาจต้องการตั้งค่าPATHใน~/.bash_profileหรือ~/.bashrc.


1

ในการทุบตีคุณสามารถ $ {var / find / replace}

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

หรือในกรณีนี้ (เนื่องจากบิตแทนที่ว่างเปล่า) เพียงแค่:

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

ฉันมาที่นี่ก่อน แต่ไปใช้เครื่องอื่นเพราะฉันคิดว่าจะมีการขยายพารามิเตอร์เพื่อทำสิ่งนี้ ง่ายกว่า sed!.

จะแทนที่อักขระตัวยึดตำแหน่งหรือคำในตัวแปรด้วยค่าจากตัวแปรอื่นใน Bash ได้อย่างไร


%หมายถึงการจับคู่หากอยู่ท้ายสตริง#เป็นจุดเริ่มต้น
sabgenton

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::`

วิธีนี้คุณไม่จำเป็นต้องหนีเครื่องหมายทับสำหรับตัวดำเนินการทดแทน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.