ทำไม ~ / .bash_profile ไม่ได้รับแหล่งที่มาเมื่อเปิดเทอร์มินัล


175

ปัญหา

ฉันมี Ubuntu 11.04 Virtual Machine และฉันต้องการตั้งค่าสภาพแวดล้อมการพัฒนา Java ของฉัน ฉันทำดังนี้

  1. sudo apt-get install openjdk-6-jdk
  2. เพิ่มรายการต่อไปนี้ใน~ / .bash_profile

    export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
    
    export PATH=$PATH:$JAVA_HOME/bin
    
  3. บันทึกการเปลี่ยนแปลงและออก

  4. เปิดเทอร์มินัลอีกครั้งและพิมพ์ดังต่อไปนี้

    echo $JAVA_HOME   (blank)
    echo $PATH        (displayed, but not the JAVA_HOME value)
    
  5. ไม่มีอะไรเกิดขึ้นเช่นถ้าการส่งออกของ JAVA_HOME และการเพิ่มไปยัง PATH นั้นไม่เคยทำ

วิธีการแก้

ฉันต้องไปที่~ / .bashrcและเพิ่มรายการต่อไปนี้ในตอนท้ายของไฟล์

#Source bash_profile to set JAVA_HOME and add it to the PATH because for some reason is not being picked up
. ~/.bash_profile

คำถาม

  1. ทำไมฉันต้องทำอย่างนั้น? ฉันคิดว่า bash_profile, bash_login หรือโพรไฟล์ในกรณีที่ไม่มีการดำเนินการสองอย่างนี้ก่อนดำเนินการก่อน bashrc
  2. ในกรณีนี้เทอร์มินัลของฉันเป็นเชลล์ที่ไม่ใช่การเข้าสู่ระบบหรือไม่
  3. ถ้าเป็นเช่นนั้นทำไมเมื่อทำ su หลังจากเทอร์มินัลและใส่รหัสผ่านมันไม่ได้ดำเนินการโปรไฟล์ที่ฉันได้ตั้งค่าการส่งออกดังกล่าวข้างต้น?

คำตอบ:


224

~/.bash_profileมีแหล่งที่มาโดย bash เมื่อเริ่มต้นในโหมดเข้าสู่ระบบแบบโต้ตอบ โดยทั่วไปจะเป็นเมื่อคุณลงชื่อเข้าใช้ที่คอนโซล ( Ctrl+ Alt+ F1.. F6) หรือเชื่อมต่อผ่าน ssh

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

เมื่อคุณเปิดขั้วขั้วเริ่มทุบตีใน (ยังไม่ได้เข้าสู่ระบบ) ~/.bashrcโหมดโต้ตอบซึ่งหมายความว่ามันจะมา

สถานที่ที่เหมาะสมสำหรับคุณที่จะนำตัวแปรสภาพแวดล้อมเหล่านี้~/.profileมาใช้และควรเห็นผลกระทบในครั้งต่อไปที่คุณเข้าสู่ระบบ

การจัดหา~/.bash_profileจาก~/.bashrcนั้นเป็นทางออกที่ผิด มันควรจะเป็นวิธีอื่น ๆ ควรจะมา~/.bash_profile~/.bashrc

ดูDotFilesสำหรับคำอธิบายที่ละเอียดยิ่งขึ้นรวมถึงประวัติว่าทำไมมันถึงเป็นเช่นนั้น

(ในหมายเหตุด้านเมื่อติดตั้ง openjdk ผ่าน apt ควรมีการตั้งค่า symlink โดยแพ็คเกจเพื่อให้คุณไม่จำเป็นต้องตั้งค่าJAVA_HOMEหรือเปลี่ยนแปลงPATH)


6
ฉันพบว่าเมื่อเปิด Terminal จากแถบด้านข้างใน Ubuntu 12 ไฟล์ ~ / .profile จะไม่ถูกโหลด
jcollum

3
@jcollum นั่นเป็นเรื่องดี .profileควรจะเป็นแหล่งที่มาเท่านั้นเมื่อคุณเข้าสู่ระบบ
geirha

2
โอ้ terminal เปิดไม่ได้เป็นเช่นเดียวกับการเข้าสู่ระบบ ... ผมคิดว่าการเข้าสู่ระบบไปยังสถานี
jcollum

2
จำไว้ว่า.profileไม่ใช้ bash หาก.bash_profileมีอยู่ ดูคำตอบของฉันที่นี่ และman bashสำหรับรายละเอียดเพิ่มเติม
terdon

3
@terdon ใช่ .profileแต่ทุบตีไม่เกี่ยวข้องกับเมื่อเข้าสู่ระบบกราฟิกดังนั้นมันจะไปตรง
geirha

48

คุณสามารถตรวจสอบว่า Bash shell ของคุณเริ่มต้นเป็น login-shell หรือไม่โดยรัน:

shopt login_shell

ถ้าคำตอบคือoffคุณไม่ได้ใช้เชลล์ล็อกอิน

อ่านส่วนการร้องขอของ Bash ด้วยตนเองเกี่ยวกับวิธีการที่ Bash อ่าน (หรือไม่อ่าน) ไฟล์การกำหนดค่าต่างๆ

ตัดตอนมาจากman bash:

เมื่อ bash ถูกเรียกใช้เป็นเชลล์ล็อกอินแบบโต้ตอบหรือเป็นเชลล์ที่ไม่มีการโต้ตอบพร้อมกับ--login ตัวเลือกมันจะอ่านและเรียกใช้คำสั่งจากไฟล์/etc/profileก่อนหากไฟล์นั้นมีอยู่ หลังจากที่ได้อ่านแฟ้มที่จะมองหา ~/.bash_profile, ~/.bash_loginและ~/.profileในลำดับที่และอ่านและรันคำสั่งจากคนแรกที่มีอยู่และสามารถอ่านได้

suในทางกลับกันก็ไม่ได้เริ่มต้นเปลือกเข้าสู่ระบบโดยค่าเริ่มต้นคุณต้องบอกให้ทำเช่นนั้นโดยใช้--loginตัวเลือก


9
ขอบคุณมากสำหรับคำสั่งshotp login_shell น่ากลัว !!
Viriato

27

ฉันคิดว่าเป็นมูลค่าการกล่าวขวัญว่าคุณสามารถเปลี่ยนค่าเริ่มต้นของ gnome-terminal เพื่อใช้เปลือกเข้าสู่ระบบ (เช่น. bash -l) โดยการแก้ไขการตั้งค่าโปรไฟล์

ไปที่แก้ไข -> การตั้งค่าโปรไฟล์ -> ชื่อแท็บและคำสั่งตรวจสอบตัวเลือก "เรียกใช้คำสั่งเป็นเปลือกเข้าสู่ระบบ"


1
ข้อเสียของการเปิดใช้งานการตั้งค่านี้คืออะไร
chrish

2
@ Chris คุณเพิ่งโหลดโค้ดอีกเล็กน้อยในจำนวนที่จำเป็น อาจไม่สำคัญว่าคุณ~/.bash_profileจะทำการประเมินอย่างรวดเร็วซึ่งอาจเป็นกรณีนี้ สิ่งที่ดีในการตรวจสอบคือไล่ล่าการเรียกไปยังกระบวนการอื่น ๆ ที่มักจะมีค่าใช้จ่ายค่อนข้างสูง
vaab

14

หากคุณเปิดเทอร์มินัลหรือเรียกใช้suเชลล์จะไม่ถูกเรียกใช้งานเป็นเชลล์ล็อกอิน แต่เป็นเชลล์เชิงโต้ตอบปกติ ดังนั้นมันอ่านแต่ไม่~/.bashrc ~/.bash_profileคุณสามารถรันsuด้วย-lตัวเลือกเพื่อให้เชลล์ของคุณใช้เป็นเชลล์ล็อกอิน

เมื่อคุณทำงานกับ GUI เชลล์มักจะไม่ทำงานเป็นเชลล์ล็อกอินดังนั้นจึงเป็นเรื่องปกติที่คุณจะต้องใส่ทุกสิ่งลง~/.bashrcไป


1
นั่นคือสิ่งที่ฉันได้ทำไปแล้วและมันใช้งานได้ แต่ตรวจสอบสิ่งที่คนที่อยู่ด้านล่างบอกว่าเขาแนะนำว่าเป็นความคิดที่ดีที่จะใส่ไว้ใน bashrc และวางมันลงบนโปรไฟล์แทน .... เฮ้ทั้งสองวิธีทำงานขอบคุณมาก
Viriato

4

TL; DR

ในการติดตั้ง Ubuntu แบบคลาสสิกที่แนะนำ~/.bash_profileจะได้รับการประเมินในบางโอกาสเท่านั้น และมันก็สมเหตุสมผล

ใส่ข้อมูลของคุณเข้าไป~/.bashrcมันจะได้รับการประเมินทุกครั้ง

ตกลงฉันต้องการที่จะเข้าใจว่าทำไมมันถึงสมเหตุสมผล?

ประเด็นสำคัญที่จะเข้าใจสิ่งที่เกิดขึ้น:

  • กระบวนการทั้งหมดบน linux มีและใช้ตัวแปรสภาพแวดล้อม
  • ตัวแปรสภาพแวดล้อมได้รับการสืบทอด
  • ดังนั้นการตั้งค่าให้พ่อของทุกกระบวนการของคุณเพียงครั้งเดียวก็เพียงพอแล้ว (โดยเฉพาะถ้ามันต้องใช้เวลาในการคำนวณ)
  • โดยทั่วไปพ่อของกระบวนการทั้งหมดของคุณจะเปิดตัวหลังจากคุณ เข้าสู่ระบบบนอุปกรณ์ของคุณ (ให้ข้อมูลประจำตัวของคุณ)
  • มีบางสิ่งที่คุณอาจต้องการทำเพียงครั้งเดียวเมื่อคุณลงชื่อเข้าใช้บนคอมพิวเตอร์ของคุณ (ตรวจสอบอีเมลใหม่เช่น ... )

ดังนั้นเวลา "เข้าสู่ระบบ" จึงเป็นดังนี้:

  • ในโหมดคอนโซลเมื่อคุณเข้าสู่ระบบ (ด้วยการกด Ctrl-Alt F1) หรือผ่านเช่นเปลือกจะเป็นบิดาของกระบวนการทั้งหมดก็จะโหลดของคุณssh ~/.bash_profile
  • ในโหมดกราฟิกเมื่อคุณเปิดเซสชั่นของคุณขั้นตอนแรก ( gnome-sessionสำหรับอูบุนตูคลาสสิก)
    .profileจะรับผิดชอบในการอ่าน

ตกลงดังนั้นสิ่งที่จะนำสิ่งที่ฉัน?

มันค่อนข้างซับซ้อนเรื่องเต็มอยู่ที่นี่ แต่นี่คือการเรียกใช้ที่ค่อนข้างธรรมดาสำหรับผู้ใช้ Ubuntu ดังนั้นเมื่อพิจารณาแล้ว:

  • คุณใช้bashเปลือกหอย
  • คุณมี~/.bash_profileและปฏิบัติตามคำแนะนำเพื่อเพิ่มโหลดของ~/.bashrcในของคุณ~/.bash_profileเพื่อให้ได้รับอย่างน้อยหนึ่งไฟล์ที่ได้รับการประเมินสิ่งที่อยู่ mecanism

นี่เป็นข้อเสนอแนะอย่างรวดเร็วว่าจะใส่อะไรดี

  • ~ / .bashrc (ได้รับการประเมินในทุกโอกาสให้คุณทำตามคำแนะนำ)

    สำหรับตัวแปรสภาพแวดล้อมและโค้ดสำหรับการประเมินผลอย่างรวดเร็วสำหรับการใช้งานบรรทัดคำสั่งของ ผู้ใช้เท่านั้นและbash-only (ตัวอย่างเช่นนามแฝง) ยินดีต้อนรับbashism

    มันได้รับการโหลดในตัวเองเมื่อ:

    • สร้างเชลล์หน้าต่าง / บานหน้าต่างใหม่ในเซสชันกราฟิก
    • การเรียกร้อง bash
    • screenบานหน้าต่างหรือแท็บใหม่ (ไม่ใช่tmux!)
    • อินสแตนซ์ bash ใด ๆ ในไคลเอ็นต์คอนโซลกราฟิก ( terminator/ gnome-terminal... ) หากคุณไม่ เลือกตัวเลือก "run command as login shell"

    และมันจะได้รับการโหลดในทุกโอกาสอื่น ๆ ขอบคุณคำแนะนำก่อนหน้า

  • ~ / .bash_profile (ได้รับการประเมินในบางโอกาสเท่านั้น )

    สำหรับตัวแปรสภาพแวดล้อมการประเมินผลช้าและรหัสสำหรับกระบวนการผู้ใช้และคอนโซลเซสชันของคุณ ยินดีต้อนรับbashism มันได้รับการโหลดเมื่อ:

    • เข้าสู่ระบบคอนโซล (Ctrl-Alt F1)
    • ssh เข้าสู่ระบบไปยังเครื่องนี้
    • tmuxบานหน้าต่างหรือหน้าต่างใหม่ (การตั้งค่าเริ่มต้น) (ไม่ใช่screen!)
    • โทรที่ชัดเจนของbash -l,
    • อินสแตนซ์ bash ใด ๆ ในไคลเอ็นต์คอนโซลกราฟิก ( terminator/ gnome-terminal... ) เฉพาะเมื่อคุณทำเครื่องหมายที่ตัวเลือก "รันคำสั่งเป็นล็อกอินเชลล์"
  • ~ / .profile (ได้รับการประเมินในกราฟิกเซสชั่นเท่านั้น)

    สำหรับตัวแปรสภาพแวดล้อมการประเมินผลช้าและไม่มี bashism สำหรับผู้ใช้เท่านั้นและกระบวนการเซสชันกราฟิกทั้งหมดของคุณ มันถูกโหลดเมื่อเข้าสู่ระบบใน UI กราฟิกของคุณ


ในบางครั้งที่ bash ทำการโหลดไฟล์โปรไฟล์มันจะทำการโหลด.profileหาก.bash_profileไม่มีอยู่
muru

ขอบคุณมากสำหรับคำอธิบายที่ชัดเจน มันช่วยมือใหม่อย่างฉัน ใน Mac Mojave ถ้าฉันใส่ตัวแปรใน ~ / .bashrc และทำซอร์สแล้วถ้าฉันทำenvฉันไม่เห็นชุดตัวแปร env (ฉันลองปิด iTerm และเปิดใหม่) แต่ผมสังเกตเห็นว่าเมื่อติดตั้งสตูดิโอ Android และปพลิเคชันอื่น ๆ ทุกคน vars env /.bash_profileที่ตั้งอยู่ใน ดังนั้นเมื่อฉันเพิ่มเข้าไป/.bash_profileมันก็ทำงานเหมือนมีเสน่ห์ ทำไมถึงเป็นอย่างนั้น?
sofs1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.