วิธีเพิ่มเส้นทางไปยัง PATH อย่างถูกต้องได้อย่างไร


922

ฉันสงสัยว่าจะต้องเพิ่มพา ธ ใหม่ในPATHตัวแปรสภาพแวดล้อมที่ไหน ฉันรู้ว่านี่สามารถทำได้โดยการแก้ไข.bashrc(ตัวอย่าง) แต่ยังไม่ชัดเจนว่าจะทำอย่างไร

ทางนี้:

export PATH=~/opt/bin:$PATH

หรือสิ่งนี้

export PATH=$PATH:~/opt/bin

printf '\ nPATH = $ PATH: "path-to-add" \ nexport PATH \ n' >> ~ / .bashrc
Sudoer


ถ้ามีอยู่แล้วบางเส้นทางเพิ่มเช่นPATH=$PATH:$HOME/.local/bin:$HOME/binอีกสามารถเพิ่มได้โดยแยกกับ: PATH=$PATH:$HOME/.local/bin:$HOME/bin:/home/ec2-user/pear/binเช่น
Sandeepan Nath

2
คำตอบเหล่านี้ใช้ได้กับ linux ทุกรสชาติหรือไม่
Ungeheuer

คำตอบ:


1033

เรื่องง่าย ๆ

PATH=$PATH:~/opt/bin

หรือ

PATH=~/opt/bin:$PATH

ขึ้นอยู่กับว่าคุณต้องการเพิ่ม~/opt/binที่ส่วนท้าย (จะค้นหาหลังจากไดเรกทอรีอื่นทั้งหมดในกรณีที่มีโปรแกรมชื่อเดียวกันในหลายไดเรกทอรี) หรือที่จุดเริ่มต้น (จะค้นหาก่อนไดเรกทอรีอื่นทั้งหมด)

คุณสามารถเพิ่มหลายรายการในเวลาเดียวกัน PATH=$PATH:~/opt/bin:~/opt/node/binหรือรูปแบบในการสั่งซื้อทำงานได้ดี อย่าวางexportที่จุดเริ่มต้นของบรรทัดเนื่องจากมีภาวะแทรกซ้อนเพิ่มเติม (ดูด้านล่างภายใต้“ หมายเหตุเกี่ยวกับหอยอื่นที่ไม่ใช่ทุบตี”)

หากคุณPATHได้รับการสร้างขึ้นโดยองค์ประกอบที่แตกต่างกันคุณอาจท้ายด้วยรายการที่ซ้ำกัน ดูวิธีเพิ่มพา ธ โฮมไดเร็กทอรีที่จะค้นพบโดย Unix คำสั่งใด? และลบรายการ $ PATH ที่ซ้ำกันด้วยคำสั่ง awkเพื่อหลีกเลี่ยงการเพิ่มรายการที่ซ้ำหรือลบออก

การแจกแจงบางอย่างจะใส่~/binเส้นทางของคุณโดยอัตโนมัติถ้ามี

จะวางตรงไหน

ใส่เส้นในการปรับเปลี่ยนPATHใน~/.profileหรือ~/.bash_profileถ้านั่นคือสิ่งที่คุณมี

โปรดทราบว่า~/.bash_rcจะไม่อ่านโดยโปรแกรมใด ๆ และ~/.bashrcเป็นไฟล์กำหนดค่าของอินสแตนซ์โต้ตอบของทุบตี ~/.bashrcคุณไม่ควรที่จะกำหนดตัวแปรสภาพแวดล้อมใน สถานที่ที่เหมาะสมในการกำหนดตัวแปรสภาพแวดล้อมเช่นPATHเป็น~/.profile(หรือ~/.bash_profileถ้าคุณไม่สนใจเกี่ยวกับเปลือกหอยอื่น ๆ กว่าทุบตี) ดูความแตกต่างระหว่างพวกเขากับสิ่งใดที่ฉันควรใช้

อย่าวางไว้ใน/etc/environmentหรือ~/.pam_environment: ไฟล์เหล่านี้ไม่ใช่ไฟล์เชลล์คุณไม่สามารถใช้การแทนที่เช่น$PATHนั้นได้ ในไฟล์เหล่านี้คุณสามารถแทนที่ตัวแปรได้เท่านั้นไม่สามารถเพิ่มตัวแปรได้

ภาวะแทรกซ้อนที่อาจเกิดขึ้นในสคริปต์ระบบบางตัว

คุณไม่ต้องการexportถ้าตัวแปรอยู่ในสภาพแวดล้อมอยู่แล้ว: การเปลี่ยนแปลงใด ๆ ของค่าของตัวแปรนั้นจะสะท้อนให้เห็นในสภาพแวดล้อมPATH¹ค่อนข้างอยู่ในสภาพแวดล้อมเสมอ ระบบยูนิกซ์ทั้งหมดตั้งค่าตั้งแต่ต้น (โดยปกติจะอยู่ในกระบวนการแรกจริง ๆ )

ณ เวลาล็อกอินคุณสามารถพึ่งพาPATHสภาพแวดล้อมที่มีอยู่แล้วและมีไดเรกทอรีระบบบางส่วนอยู่แล้ว หากคุณกำลังเขียนสคริปต์ที่อาจทำงานได้เร็วในขณะที่ตั้งค่าสภาพแวดล้อมเสมือนบางประเภทคุณอาจต้องตรวจสอบให้แน่ใจว่าPATHไม่ว่างเปล่าและส่งออก: หากPATHยังไม่ได้ตั้งค่าสิ่งที่ต้องการPATH=$PATH:/some/directoryจะตั้งPATHเป็น:/some/directoryและส่วนประกอบที่ว่างเปล่า ที่จุดเริ่มต้นหมายถึงไดเรกทอรีปัจจุบัน (เช่น.:/some/directory)

if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi

หมายเหตุเกี่ยวกับหอยอื่นที่ไม่ใช่ทุบตี

ใน bash, ksh และ zsh exportเป็นไวยากรณ์พิเศษและทั้งสองPATH=~/opt/bin:$PATHและexport PATH=~/opt/bin:$PATHทำสิ่งที่ถูกต้องแม้ ในเชลล์สไตล์ Bourne / POSIX อื่น ๆ เช่น dash (ซึ่งอยู่/bin/shในหลาย ๆ ระบบ) exportจะถูกวิเคราะห์คำสั่งทั่วไปซึ่งมีความแตกต่างสองประการ:

ดังนั้นในเชลล์อย่างเส้นประให้export PATH=~/opt/bin:$PATHตั้งPATHเป็นสตริงตัวอักษร~/opt/bin/:ตามด้วยค่าPATHสูงสุดของช่องว่างแรก PATH=~/opt/bin:$PATH(การบ้านเปล่า) ไม่ต้องการคำพูดและทำสิ่งที่ถูกต้อง หากคุณต้องการใช้exportในสคริปต์แบบพกพาคุณต้องเขียนexport PATH="$HOME/opt/bin:$PATH"หรือPATH=~/opt/bin:$PATH; export PATH(หรือPATH=$HOME/opt/bin:$PATH; export PATHเพื่อความสะดวกในการพกพาแม้แต่บอร์นเชลล์ที่ไม่ยอมรับexport var=valueและไม่ได้ทำการขยายเครื่องหมายตัวหนอน)

¹ สิ่งนี้ไม่เป็นความจริงในเชลล์เป้าหมาย (เช่นในเชลล์บอร์นจริงไม่ใช่เชลล์สไตล์ POSIX ที่ทันสมัย) แต่คุณไม่น่าจะพบกับหอยเก่าเหล่านี้ได้


ยังไม่สามารถเข้าใจความซับซ้อนของการส่งออกได้ คุณช่วยทำให้มันง่ายขึ้นได้ไหม?
priojeet priyom

@priojeetpriyom คำอธิบายง่าย: exportคุณไม่จำเป็นต้อง
Gilles

ขอบคุณสำหรับคำตอบนี้โดยละเอียด คุณพูดว่า " คุณไม่ควรกำหนดตัวแปรสภาพแวดล้อมใน ~ / .bashrc " แต่โชคร้ายที่ 100% ของโปรแกรมที่ผมได้ติดตั้งในระบบของฉันที่ปรับเปลี่ยนเส้นทาง (FZF และสนิมของ Cargo) .bashrcปรับเปลี่ยนเส้นทางใน ฉันคิดว่าเพราะ FZF เขียนด้วยภาษา Rust ก็เป็นไปตามรูปแบบของ Rust
icc97

83

ทั้งสองวิธีใช้งานได้ แต่ไม่ได้ทำสิ่งเดียวกัน: องค์ประกอบของPATHถูกตรวจสอบจากซ้ายไปขวา ในตัวอย่างแรกของคุณไฟล์เรียกทำงานใน~/opt/binจะมีความสำคัญเหนือกว่าไฟล์ที่ติดตั้งไว้ตัวอย่างเช่นใน/usr/binซึ่งอาจจะใช่หรือไม่ใช่สิ่งที่คุณต้องการ

โดยเฉพาะอย่างยิ่งจากมุมมองด้านความปลอดภัยมันเป็นอันตรายที่จะเพิ่มเส้นทางไปข้างหน้าเพราะถ้าใครบางคนสามารถเข้าถึงการเขียนของคุณ~/opt/binพวกเขาสามารถใส่เช่นที่แตกต่างกันlsในที่นั่นซึ่งคุณอาจจะใช้แทน ของ/bin/lsโดยไม่สังเกตเห็น ทีนี้ลองจินตนาการถึงสิ่งเดียวกันสำหรับsshเบราว์เซอร์หรือตัวเลือกของคุณ ...


6
แต่ถ้าคุณต้องการที่จะมีตัวเองรุ่นของคุณกำหนดเองของคุณจะต้องใส่ไว้ในไดเรกทอรีข้างหน้าของls /bin
Barmar

16
or alias ls = myls
waltinator

36

ฉันสับสนด้วยคำถาม 2 (ตั้งแต่ถูกลบออกจากคำถามเนื่องจากเป็นปัญหาที่ไม่เกี่ยวข้อง):

เป็นวิธีที่ใช้งานได้เพื่อผนวกเส้นทางเพิ่มเติมในบรรทัดที่แตกต่างกันอย่างไร ตอนแรกฉันคิดว่าสิ่งนี้สามารถทำเคล็ดลับ:

export PATH=$PATH:~/opt/bin
export PATH=$PATH:~/opt/node/bin

แต่ไม่ใช่เพราะการมอบหมายครั้งที่สองไม่เพียง แต่ผนวก ~/opt/node/binแต่รวมถึงการPATHมอบหมายก่อนหน้านี้ทั้งหมด

นี่เป็นวิธีแก้ไขที่เป็นไปได้:

export PATH=$PATH:~/opt/bin:~/opt/node/bin

แต่เพื่อความสะดวกในการอ่านฉันต้องการมีหนึ่งการมอบหมายสำหรับหนึ่งเส้นทาง

ถ้าคุณพูด

PATH=~/opt/bin

นั่นคือทั้งหมดที่จะอยู่ในเส้นทางของคุณ PATH เป็นเพียงตัวแปรสภาพแวดล้อมและหากคุณต้องการเพิ่มใน PATH คุณจะต้องสร้างตัวแปรใหม่ด้วยเนื้อหาที่คุณต้องการ นั่นคือสิ่งที่คุณให้เป็นตัวอย่างของคำถามที่ 2 คือสิ่งที่คุณต้องการจะทำยกเว้นว่าฉันไม่มีจุดคำถาม

ฉันใช้ทั้งสองแบบในรหัสของฉัน ฉันมีโปรไฟล์ทั่วไปที่ฉันติดตั้งในเครื่องทุกเครื่องที่ทำงานในลักษณะนี้เพื่อรองรับไดเรกทอรีที่อาจขาดหายไป:

export PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11
# add optional items to the path
for bindir in $HOME/local/bin $HOME/bin; do
    if [ -d $bindir ]; then
        PATH=$PATH:${bindir}
    fi
done

2
คุณพูดถูกเกี่ยวกับตัวอย่างของคำถามที่ 2 ปัญหาที่เกี่ยวข้องกับเส้นทางอื่นในระบบของฉันทำให้ฉันสับสน ขอโทษสำหรับสิ่งนั้น.
เปาโล

26

วิธีพิสูจน์กระสุนของการต่อท้าย / การเตรียมการ

มีสิ่งที่ต้องพิจารณามากมายในการเลือกการต่อท้ายกับการเตรียม หลายคนได้รับการคุ้มครองในคำตอบอื่น ๆ ดังนั้นฉันจะไม่พูดซ้ำ

จุดสำคัญคือแม้ว่าสคริปต์ของระบบจะไม่ใช้สิ่งนี้ (ฉันสงสัยว่าทำไม) * 1วิธีพิสูจน์กระสุนเพื่อเพิ่มเส้นทาง (เช่น$HOME/bin) ไปยังตัวแปรสภาพแวดล้อมของ PATH คือ

PATH="${PATH:+${PATH}:}$HOME/bin"

สำหรับการต่อท้าย (แทนPATH="$PATH:$HOME/bin") และ

PATH="$HOME/bin${PATH:+:${PATH}}"

สำหรับการเตรียมการ (แทนPATH="$HOME/bin:$PATH")

นี้หลีกเลี่ยงการชั้นนำของปลอม / ท้ายลำไส้ใหญ่เมื่อ$PATHเป็นครั้งแรกที่ว่างเปล่าซึ่งจะมีผลข้างเคียงที่ไม่พึงประสงค์และสามารถกลายเป็นฝันร้ายที่เข้าใจยากที่จะหา ( คำตอบนี้สั้น ๆ ที่เกี่ยวข้องกับกรณีที่awk-way)

คำอธิบาย (จากการขยายพารามิเตอร์ของเชลล์ ):

${parameter:+word}

หากparameterเป็นโมฆะหรือไม่มีการตั้งค่าจะไม่มีสิ่งใดถูกทดแทนมิฉะนั้นการขยายwordจะถูกแทนที่

ดังนั้น${PATH:+${PATH}:}จะขยายเป็น: 1) ไม่มีอะไรเลยถ้าPATHเป็นโมฆะหรือไม่มีการตั้งค่า 2) ${PATH}:หากPATHตั้งไว้

หมายเหตุ : นี่สำหรับทุบตี


* 1ฉันเพิ่งพบว่าสคริปต์อย่างdevtoolset-6/enableนี้ใช้งานได้จริง

$ cat /opt/rh/devtoolset-6/enable
# General environment variables
export PATH=/opt/rh/devtoolset-6/root/usr/bin${PATH:+:${PATH}}
...

24

Linux กำหนดพา ธ การค้นหาที่ปฏิบัติการได้ด้วย$PATHตัวแปรสภาพแวดล้อม ในการเพิ่มไดเร็กทอรี / data / myscripts ไปยังจุดเริ่มต้นของ$PATHตัวแปรสภาพแวดล้อมให้ใช้ดังต่อไปนี้:

PATH=/data/myscripts:$PATH

ในการเพิ่มไดเรกทอรีนั้นไปยังจุดสิ้นสุดของเส้นทางให้ใช้คำสั่งต่อไปนี้:

PATH=$PATH:/data/myscripts

แต่ก่อนหน้านี้ไม่เพียงพอเพราะเมื่อคุณตั้งค่าตัวแปรสภาพแวดล้อมภายในสคริปต์การเปลี่ยนแปลงนั้นจะมีผลเฉพาะภายในสคริปต์ ข้อ จำกัด นี้มีสองวิธีเท่านั้น:

  • หากภายในสคริปต์คุณจะส่งออกตัวแปรสภาพแวดล้อมซึ่งมีผลบังคับใช้ภายในโปรแกรมใด ๆ ที่สคริปต์เรียกใช้ โปรดทราบว่าไม่มีประสิทธิภาพในโปรแกรมที่เรียกใช้สคริปต์
  • หากโปรแกรมที่เรียกใช้สคริปต์ดำเนินการดังกล่าวโดยการรวมแทนการโทรการเปลี่ยนแปลงสภาพแวดล้อมใด ๆ ในสคริปต์จะมีผลภายในโปรแกรมที่เรียกใช้ การรวมดังกล่าวสามารถทำได้ด้วยคำสั่ง dot หรือคำสั่ง source

ตัวอย่าง:

$HOME/myscript.sh
source $HOME/myscript.sh

โดยทั่วไปแล้วการรวมจะรวมสคริปต์ "เรียกว่า" ในสคริปต์ "เรียก" มันเหมือนกับ #include ใน C ดังนั้นมันจึงมีประสิทธิภาพในสคริปต์หรือโปรแกรม "การโทร" แต่แน่นอนว่ามันไม่มีประสิทธิภาพในโปรแกรมหรือสคริปต์ใด ๆ ที่เรียกโดยโปรแกรมเรียก เพื่อให้มีประสิทธิภาพตลอดสายการโทรคุณต้องปฏิบัติตามการตั้งค่าของตัวแปรสภาพแวดล้อมด้วยคำสั่งส่งออก

เป็นตัวอย่างโปรแกรม bash shell รวมเนื้อหาของไฟล์. bash_profile โดยการรวม วาง 2 บรรทัดต่อไปนี้ใน. bash_profile:

PATH=$PATH:/data/myscripts
export PATH

วางโค้ด 2 บรรทัดเหล่านั้นในโปรแกรม bash อย่างมีประสิทธิภาพ ดังนั้นภายใน bash ตัวแปร $ PATH รวมถึง$HOME/myscript.shและเนื่องจากคำสั่งการส่งออกโปรแกรมใด ๆ ที่ถูกเรียกโดย bash จะมี$PATHตัวแปรที่เปลี่ยนแปลง และเนื่องจากโปรแกรมใด ๆ ที่คุณเรียกใช้จาก bash prompt ถูกเรียกโดย bash พา ธ ใหม่จะมีผลบังคับใช้สำหรับทุกสิ่งที่คุณเรียกใช้จาก bash prompt

บรรทัดล่างคือการเพิ่มไดเรกทอรีใหม่ไปยังเส้นทางคุณต้องผนวกหรือผนวกไดเรกทอรีกับตัวแปรสภาพแวดล้อม $ PATH ภายในสคริปต์ที่รวมอยู่ในเปลือกและคุณต้องส่งออก$PATHตัวแปรสภาพแวดล้อม

ข้อมูลเพิ่มเติมที่นี่


19

บางครั้งฉันก็เก็บฟังก์ชั่นสองอย่างของฉันไว้pathaddและpathrmช่วยในการเพิ่มองค์ประกอบให้กับเส้นทางโดยไม่ต้องกังวลกับการทำซ้ำ

pathaddใช้เวลาอาร์กิวเมนต์เส้นทางเดียวและอาร์กิวเมนต์ตัวเลือกafterซึ่งหากให้มาจะผนวกไปเป็นPATHอย่างอื่นมันจะเป็นการเตรียมมัน

ในเกือบทุกสถานการณ์หากคุณกำลังเพิ่มเส้นทางคุณอาจต้องการลบล้างสิ่งใดก็ตามที่อยู่ในเส้นทางซึ่งเป็นสาเหตุที่ฉันเลือกที่จะเพิ่มโดยค่าเริ่มต้น

pathadd() {
    newelement=${1%/}
    if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then
        if [ "$2" = "after" ] ; then
            PATH="$PATH:$newelement"
        else
            PATH="$newelement:$PATH"
        fi
    fi
}

pathrm() {
    PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
}

ใส่เหล่านี้ในสคริปต์ใด ๆ ที่คุณต้องการเปลี่ยนสภาพแวดล้อมของเส้นทางและตอนนี้คุณสามารถทำได้

pathadd "/foo/bar"
pathadd "/baz/bat" after
export PATH

คุณรับประกันว่าจะไม่เพิ่มเส้นทางหากมีอยู่แล้ว หากคุณต้องการให้แน่ใจว่า/baz/batเป็นจุดเริ่มต้น

pathrm "/baz/bat"
pathadd "/baz/bat"
export PATH

ตอนนี้เส้นทางใดก็ได้ที่สามารถย้ายไปข้างหน้าได้ถ้ามันอยู่ในเส้นทางแล้วโดยไม่ต้องเสแสร้ง


วิธีที่เกี่ยวข้องและสะอาดกว่าเพื่อตรวจสอบการมีไดเรกทอรีใน PATH ของคุณ: unix.stackexchange.com/a/32054/135943
Wildcard

9

ฉันไม่สามารถพูดถึงการกระจายอื่น ๆ ได้ แต่ Ubuntu มีไฟล์ / etc / environment นั่นคือเส้นทางการค้นหาเริ่มต้นสำหรับผู้ใช้ทั้งหมด เนื่องจากคอมพิวเตอร์ของฉันถูกใช้โดยฉันเท่านั้นฉันจึงใส่ไดเรกทอรีใด ๆ ที่ฉันต้องการในเส้นทางของฉันที่นั่นเว้นแต่จะเป็นส่วนเพิ่มเติมชั่วคราวที่ฉันใส่ไว้ในสคริปต์


6

มีบางสถานการณ์ที่การใช้PATH=/a/b:$PATHอาจถูกพิจารณาว่าเป็น "วิธีที่ไม่ถูกต้อง" ในการเพิ่มเส้นทางไปยังPATH:

  1. การเพิ่มเส้นทางที่ไม่ใช่ไดเรกทอรี
  2. การเพิ่มเส้นทางที่มีอยู่แล้วในPATHรูปแบบเดียวกัน
  3. การเพิ่มพา ธ สัมพัทธ์ (เนื่องจากไดเรกทอรีที่ค้นหาจริงจะเปลี่ยนไปเมื่อคุณเปลี่ยนไดเรกทอรีการทำงานปัจจุบัน)
  4. การเพิ่มพา ธ ที่มีอยู่แล้วในPATHรูปแบบอื่น (เช่นชื่อแทนเนื่องจากใช้ symlink หรือ..)
  5. หากคุณหลีกเลี่ยงการทำ 4 ไม่ได้เคลื่อนย้ายเส้นทางไปยังด้านหน้าของPATHเมื่อมันตั้งใจที่จะแทนที่รายการอื่น ๆ PATHใน

ฟังก์ชั่น (Bash-only) นี้ทำ "สิ่งที่ถูกต้อง" ในสถานการณ์ด้านบน (ยกเว้นดูด้านล่าง) ส่งคืนรหัสข้อผิดพลาดและพิมพ์ข้อความที่ดีสำหรับมนุษย์ รหัสข้อผิดพลาดและข้อความสามารถปิดการใช้งานเมื่อพวกเขาไม่ต้องการ

prepath() {
    local usage="\
Usage: prepath [-f] [-n] [-q] DIR
  -f Force dir to front of path even if already in path
  -n Nonexistent dirs do not return error status
  -q Quiet mode"

    local tofront=false errcode=1 qecho=echo
    while true; do case "$1" in
        -f)     tofront=true;       shift;;
        -n)     errcode=0;          shift;;
        -q)     qecho=':';          shift;;
        *)      break;;
    esac; done
    # Bad params always produce message and error code
    [[ -z $1 ]] && { echo 1>&2 "$usage"; return 1; }

    [[ -d $1 ]] || { $qecho 1>&2 "$1 is not a directory."; return $errcode; }
    dir="$(command cd "$1"; pwd -P)"
    if [[ :$PATH: =~ :$dir: ]]; then
        $tofront || { $qecho 1>&2 "$dir already in path."; return 0; }
        PATH="${PATH#$dir:}"        # remove if at start
        PATH="${PATH%:$dir}"        # remove if at end
        PATH="${PATH//:$dir:/:}"    # remove if in middle
    fi
    PATH="$dir:$PATH"
}

ข้อยกเว้นคือฟังก์ชั่นนี้ไม่ได้กำหนดเส้นทางแบบบัญญัติให้เป็นPATHทางอื่นดังนั้นหากนามแฝงที่ไม่ใช่แบบบัญญัติสำหรับเส้นทางอยู่ในPATHสิ่งนี้จะเพิ่มซ้ำ การพยายามกำหนดเส้นทางให้เป็นที่ยอมรับอยู่แล้วPATHนั้นเป็นข้อเสนอลูกเต๋าเนื่องจากเส้นทางสัมพัทธ์มีความหมายที่ชัดเจนเมื่อผ่านไปprepathแต่เมื่ออยู่ในเส้นทางแล้วคุณไม่ทราบว่าไดเรกทอรีทำงานปัจจุบันคืออะไรเมื่อมันถูกเพิ่มเข้ามา


เกี่ยวกับเส้นทางสัมพัทธ์: สิ่งที่เกี่ยวกับการมีสวิตช์ '-r' ซึ่งจะเพิ่มเส้นทางโดยไม่ทำให้มันสมบูรณ์ก่อนและสิ่งที่จะมองว่ามันเป็นสัมบูรณ์ก่อนที่จะเพิ่มหรือไม่ หากนี่คือสคริปต์คนหนึ่งสามารถใช้มันในเชลล์อื่น ๆ ได้ มีประโยชน์อะไรบ้างในการใช้เป็นฟังก์ชั่น? รหัสที่ดี!
hoijui

1
@hoijui มันจะต้องมีฟังก์ชั่นเพราะมันปรับเปลี่ยนสภาพแวดล้อมในปัจจุบัน ถ้ามันเป็นสคริปต์ก็จะปรับเปลี่ยนสภาพแวดล้อมของกระบวนการย่อยที่ใช้สคริปต์และเมื่อสคริปต์ออกคุณจะต้องเหมือนกัน$PATHในขณะที่คุณมีมาก่อน สำหรับ-rฉันไม่คิดว่าเส้นทางญาติใน$PATHนั้นไม่น่าเชื่อถือและแปลกเกินไป (เส้นทางของคุณเปลี่ยนแปลงทุกครั้งที่คุณcd!) เพื่อต้องการสนับสนุนบางอย่างเช่นนั้นในเครื่องมือทั่วไป
Curt J. Sampson

5

สำหรับฉัน (บน Mac OS X 10.9.5) การเพิ่มชื่อพา ธ (เช่น/mypathname) ไปยังไฟล์/etc/pathsทำงานได้ดีมาก

ก่อนแก้ไขให้echo $PATHส่งคืน:

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

หลังจากแก้ไข/etc/pathsและรีสตาร์ทเปลือกตัวแปร $ PATH /pathnameถูกผนวกเข้ากับ แน่นอนecho $PATHผลตอบแทน:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname

สิ่งที่เกิดขึ้นคือสิ่งที่/mypathnameผนวกเข้ากับ$PATHตัวแปร


3
ดีกว่าที่จะเพิ่มไฟล์ไปยังไดเร็กทอรี /etc/paths.d กว่าเพื่อแก้ไขไฟล์ / etc / path
rbrewer

4

ในการเพิ่มพา ธ ใหม่ให้กับPATHตัวแปรสภาพแวดล้อม:

export PATH=$PATH:/new-path/

เพื่อให้การเปลี่ยนแปลงนี้มีผลกับทุกเชลล์ที่คุณเปิดให้เพิ่มลงในไฟล์ที่เชลล์จะมาเมื่อมีการเรียกใช้ ในเปลือกหอยที่แตกต่างกันสิ่งนี้สามารถ:

  • Bash Shell: ~ / .bash_profile, ~ / .bashrc หรือโปรไฟล์
  • Korn Shell: ~ / .kshrc หรือ. profile
  • Z Shell: ~ / .zshrc หรือ. zprofile

เช่น

# export PATH=$PATH:/root/learning/bin/
# source ~/.bashrc
# echo $PATH

คุณสามารถดูเส้นทางที่ให้ไว้ในผลลัพธ์ข้างต้น


4

นี่คือทางออกของฉัน:

PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")

ซับง่ายหนึ่งดีที่ไม่ทิ้งร่องรอย :


1
-bash: awk: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว
-bash

1
@davidcondrey - awk และ sed เป็นคำสั่งภายนอกที่ใช้กันทั่วไป คำตอบนี้ให้วิธีการทุบตีที่บริสุทธิ์ในการบรรลุเป้าหมายเดียวกันดังนั้นจึงสามารถใช้งานได้แม้ในกรณีที่ไม่มี awk และ / หรือ sed อยู่ (หรือไดเรกทอรีของพวกเขาไม่ได้อยู่ในเส้นทาง!)
sancho.s
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.