ตัวแปรสภาพแวดล้อมใน bash_profile หรือ bashrc?
ฉันได้พบคำถามนี้แล้ว [บล็อก]: ความแตกต่างระหว่าง. bashrc และ. bash_profileมีประโยชน์มาก แต่หลังจากได้เห็นคำตอบที่ได้รับการโหวตมากที่สุด (ดีมาก) ฉันมีคำถามเพิ่มเติม ในตอนท้ายของคะแนนโหวตมากที่สุดคำตอบที่ถูกต้องฉันเห็นข้อความดังนี้:
โปรดทราบว่าคุณอาจเห็นที่นี่และมีคำแนะนำให้ใส่นิยามตัวแปรสภาพแวดล้อมใน ~ / .bashrc หรือเปิดเชลล์ล็อกอินในเทอร์มินัลเสมอ ทั้งสองเป็นความคิดที่ไม่ดี
ทำไมมันถึงเป็นความคิดที่ไม่ดี (ฉันไม่ได้พยายามต่อสู้ฉันแค่อยากเข้าใจ)
หากฉันต้องการตั้งค่าตัวแปรสภาพแวดล้อมและเพิ่มลงใน PATH (เช่น JAVA_HOME) ตำแหน่งที่ดีที่สุดในการใส่รายการส่งออกจะเป็นอย่างไร ใน~ / .bash_profileหรือ~ / .bashrc ?
หากคำตอบสำหรับคำถามหมายเลข 2 คือ~ / .bash_profileฉันมีคำถามเพิ่มเติมอีกสองข้อ:
3.1. คุณจะใส่อะไรใต้~ / .bashrc ? นามแฝงเท่านั้น?
3.2. ในเชลล์ที่ไม่ใช่ล็อกอินฉันเชื่อว่า~ / .bash_profileไม่ถูก "หยิบขึ้นมา" หากการเอ็กซ์พอร์ตรายการ JAVA_HOME อยู่ใน bash_profile ฉันจะสามารถรันคำสั่งjavac & java ได้หรือไม่ จะพบพวกเขาบนเส้นทางหรือไม่? นั่นเป็นเหตุผลว่าทำไมโพสต์และฟอรัมบางแห่งจึงแนะนำให้ตั้งค่า JAVA_HOME และเหมือนกันเป็น~ / .bashrc ?
ขอบคุณล่วงหน้า.
คำตอบ
ในระบบสมัยใหม่ไม่ใช่เรื่องปกติโดยเฉพาะอย่างยิ่งที่จะต้องเผชิญกับกรณีที่มีความสำคัญ แต่จะเกิดขึ้น (โดยเฉพาะอย่างยิ่งถ้าคุณใช้การดำเนินการของเชลล์ในรูปแบบvimเช่น:r !commandหรือในบรรทัด!<motion>command)
คุณจะใส่อะไรใต้ ~ / .bashrc? นามแฝงเท่านั้น?
คุณใส่สิ่ง~/.bashrcที่จะไม่สืบทอดโดย subshells โดยอัตโนมัติ ซึ่งหมายถึงนามแฝงและฟังก์ชันโดยส่วนใหญ่แม้ว่าบางครั้งคุณจะมีการตั้งค่าตัวแปรที่คุณไม่ต้องการให้มองเห็นภายนอกเชลล์ (ซึ่งหายากมาก) อาจเป็นที่ถกเถียงกันอยู่ว่าสิ่งเหล่านี้ควรได้รับการส่งออกอย่างใด แต่ความพยายามในการทดลองหลายครั้งประสบปัญหาความเข้ากันได้โดยพยายามซ่อนไว้ในสิ่งแวดล้อมและส่วนใหญ่ถูกละทิ้ง
ถ้าฉันต้องการตั้งค่าตัวแปรสภาพแวดล้อมและเพิ่มลงใน PATH (เช่น JAVA_HOME) ตำแหน่งที่ดีที่สุดในการใส่รายการส่งออกจะเป็นอย่างไร ใน ~ / .bash_profile หรือ ~ / .bashrc?
คุณใส่การตั้งค่าสภาพแวดล้อม~/.bash_profileเพื่อให้ได้รับการตั้งค่าเริ่มต้นที่ดี บางครั้งคุณอาจต้องการลบล้างสิ่งเหล่านี้ (โดยมากจะทำโดยสภาพแวดล้อมที่ซับซ้อนเช่น Matlab หรือ Cadence) หากคุณใส่การตั้งค่าสภาพแวดล้อม~/.bashrcเชลล์ที่รันจากภายในสภาพแวดล้อมเหล่านั้นจะสูญเสียการปรับแต่งสภาพแวดล้อมและสิ่งต่างๆอาจทำงานไม่ถูกต้อง นอกจากนี้ยังนำถ้าคุณใช้แพคเกจเช่นโมดูล , virtualenv , RVMฯลฯ ในการจัดการสภาพแวดล้อมการพัฒนาหลาย ๆ การตั้งค่าของคุณ~/.bashrcหมายความว่าคุณไม่สามารถเรียกใช้สภาพแวดล้อมที่คุณต้องการจากภายในตัวแก้ไขของคุณได้ แต่จะถูกบังคับให้เป็นค่าเริ่มต้นของระบบแทน
ในเชลล์ที่ไม่ใช่ล็อกอินฉันเชื่อว่า ~ / .bash_profile ไม่ถูก "หยิบขึ้นมา"
ถูกต้อง โดยปกติคุณต้องการให้เชลล์เริ่มต้นเป็นเชลล์ล็อกอินและเชลล์ใด ๆ ที่เริ่มต้นภายใต้เชลล์นั้นไม่ใช่เชลล์ล็อกอิน หากเชลล์เริ่มต้นไม่ใช่เชลล์ล็อกอินคุณจะไม่มีค่าเริ่มต้นPATHหรือการตั้งค่าอื่น ๆ (รวมถึงJAVA_HOMEตัวอย่างของคุณ)
สภาพแวดล้อมเดสก์ท็อปส่วนใหญ่ที่เปิดใช้งานจากตัวจัดการการแสดงผล (กล่าวคือล็อกอินแบบกราฟิกส่วนใหญ่) ไม่ได้ตั้งค่าสภาพแวดล้อมการเข้าสู่ระบบสำหรับเดสก์ท็อปทั้งหมดดังนั้นคุณจึงถูกบังคับให้เรียกใช้เชลล์เริ่มต้นในเทอร์มินัลเป็นเชลล์ล็อกอิน สิ่งนี้ทำให้เกิดปัญหาหลายประการ (โดยเฉพาะอย่างยิ่งPATHและสิ่งที่พร้อมใช้งานสำหรับโปรแกรมที่เรียกใช้จากเช่นพาเนลไม่ได้ตั้งค่าอย่างถูกต้องเนื่องจากพาเนลไม่ใช่เทอร์มินัลและไม่ได้ทำงาน~/.bash_profile) แต่เป็นการประนีประนอมที่สมเหตุสมผลเนื่องจากไม่สามารถทำได้ตลอดเวลา เพื่อรันอย่างมีสติ~/.bash_profileในสภาพแวดล้อมที่ไม่โต้ตอบเมื่อเริ่มต้นเซสชันที่เริ่มโดยตัวจัดการการแสดงผลขึ้นอยู่กับเนื้อหา บางครั้งแนะนำให้วางการตั้งค่าสภาพแวดล้อม~/.bashrcแทนการกำหนดค่าล็อกอินเชลล์แทน ตามที่กล่าวไว้ข้างต้นงานนี้ตราบใดที่คุณไม่จำเป็นต้องแทนที่สภาพแวดล้อมที่และทำให้เกิดการแตกหักแปลกเมื่อคุณทำจำเป็นต้องทำเช่นนั้น
เมื่อเร็ว ๆ นี้ฉันได้ช่วยวินิจฉัยปัญหาเช่นนี้บน OS X ซึ่งผู้ใช้ที่ตั้งค่าไว้ใน~/.bashrcภายหลังได้เริ่มใช้rvmและperlbrewเห็นพฤติกรรมแปลก ๆ เนื่องจากสภาพแวดล้อมที่ทั้งสองตั้งค่าไว้นั้น "ยกเลิก" โดย~/.bashrcบรรณาธิการภายในและsudo(ซึ่งใน OS X ซึ่งแตกต่างจาก Linux คือเผยแพร่ผู้ใช้$HOMEเพื่อให้ผู้ใช้~/.bashrcถูกเรียกใช้โดยรูทเชลล์) ก่อนที่จะลองใช้สภาพแวดล้อมเหล่านั้นไม่มีปัญหา เมื่อเริ่มใช้งานพวกเขารู้สึกสับสนกับการสูญเสียการตั้งค่าที่ไม่คาดคิด
พูดตามตรงวันนี้มีความแตกต่างเล็กน้อยแม้จะมีสิ่งที่กูรูพูด
ปัญหาที่อยู่เบื้องหลังนี้คือปัจจุบันเราเข้าสู่ระบบแบบกราฟิกมากกว่าการเข้าสู่ระบบเชลล์ ในอดีตเราผู้ใช้ unix ต้องการดูรายงานสั้น ๆ ว่าเกิดอะไรขึ้นบนเซิร์ฟเวอร์ทันทีหลังจากล็อกอิน - จากนั้นเราจะเริ่ม X ตามบรรทัดคำสั่ง - รายงานเหล่านี้มักจะต้องใช้เวลาในการสร้าง (เช่น 10-20 วินาที) แล้วเราก็ไม่อยากเห็นสิ่งเดียวกันเมื่อเราเริ่มเช่น xterm ดังนั้นความแตกต่าง
ทุกวันนี้ฉันไม่คิดว่าความแตกต่างมีความสำคัญในตอนนี้ ฉันคิดว่าทุกวันนี้ถ้าคุณหาแหล่ง bashrc ใน bash_profile ไม่มีใครสามารถตำหนิคุณได้
โปรดทราบว่าสิ่งนี้ใช้ไม่ได้กับ macos x (ทุกเทอร์มินัลแอปเริ่มต้นคือเชลล์ล็อกอิน)
เกี่ยวกับ "การเข้าสู่ระบบแบบกราฟิก" ขึ้นอยู่กับว่าคุณใช้ * DM ใด ...
ด้วย GDM (Gnome 3.18) ฉันมีสิ่งนี้:
/ etc / gdm / Xsession
#!/bin/sh   <= *important*
...
# First read /etc/profile and .profile
test -f /etc/profile && . /etc/profile
test -f "$HOME/.profile" && . "$HOME/.profile"
# Second read /etc/xprofile and .xprofile for X specific setup
test -f /etc/xprofile && . /etc/xprofile
test -f "$HOME/.xprofile" && . "$HOME/.xprofile"
 
     ดังนั้น~ / .profile จึงได้รับที่มาในการเข้าสู่ระบบโดยใช้/ bin / shและไม่ใช่/ bin / bash
มีสองกรณี
- / bin / shเชื่อมโยงกับ/ bin / bashแต่ทำงานในโหมด "POSIX / Bourne"
 - / bin / shคือ/ bin / dash (debian / ubuntu) เร็วที่สุด แต่มีคุณสมบัติน้อยกว่า(รองรับ ShellShock;) )
 
ดังนั้นโปรไฟล์ / bin / sh คือ~ / .profileและไม่ใช่ ~ / .bash_profile, ~ / .zprofile
ไฟล์นี้ควรใช้สำหรับการตั้งค่า"เชลล์ไม่เชื่อเรื่องพระเจ้า"เช่นตัวแปรเส้นทางและสภาพแวดล้อม
ไม่ควรมีโปรแกรมปฏิบัติการสำหรับการโต้ตอบกับผู้ใช้ที่เข้าสู่ระบบเท่านั้น แต่ที่นี่ (เช็คเมลโชคลาภ ฯลฯ ... )
~ /.* rc มีไว้สำหรับเซสชัน "โต้ตอบ" เท่านั้น (ชื่อแทนเช่น ... )
มีความแตกต่างระหว่าง bash และ zsh สำหรับเชลล์ล็อกอินแบบโต้ตอบ
bash ซอร์สเท่านั้น. bash_profile ในขณะที่ zsh ซอร์สตามลำดับ:
- ~ / .zprofile
 - ~ / .zshrc
 - ~ / zlogin (ที่นี่นามแฝงที่กำหนดไว้ใน ~ / .zshrc จะพร้อมใช้งานในกรณีของเชลล์ "โต้ตอบ" + "ล็อกอิน"
 
วิธีทำ~ / .bash_profileมีคำตอบที่นี่:
ความแตกต่างระหว่าง. bashrc และ. bash_profile
if [ -r ~/.profile ]; then . ~/.profile; fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
 
     ในการเปิดใช้งานการทดสอบ (และการสร้างโปรไฟล์) คุณสามารถใช้สิ่งนี้ได้
~ / .bash_profile:
#!/bin/bash
# ------------------------------------------------
export _DOT_BASH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------
if [ -f ~/.profile ] ; then
    . ~/.profile
fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
# ------------------------------------------------
export _DOT_BASH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------
 
     ~ / .zprofile:
#!/bin/zsh
# ------------------------------------------------
export _DOT_ZSH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------
if [ -f ~/.profile ] ; then
    . ~/.profile
fi
# no need to source, zsh already handle ~/.zshrc
###case "$-" in *i*) if [ -r ~/.zshrc ]; then . ~/.zshrc; fi;; esac
# ------------------------------------------------
export _DOT_ZSH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------
 
     จากนั้นเพื่อทดสอบ:
chsh -s /bin/bash
ssh localhost
env
exit
ssh localhost env
ssh -t localhost bash -i -c env
chsh -s /bin/zsh
ssh localhost
env
exit
ssh localhost env
ssh -t localhost bash -i -c env
 
     ดังนั้น RVM / Virtualenv ควรอยู่ใน ~ / .profile, IMHO
แต่นี้ไม่ทำงาน , บางครั้ง ...
ตัวอย่างเช่นvirualenvwrapper จะทำงานก็ต่อเมื่อเชลล์ที่รัน Xsession เป็น bash "original" (การส่งออก BASH_VERSION)
หากคุณอยู่บนระบบแดชตัวแปรสภาพแวดล้อมและการตั้งค่าพา ธ จะทำงานได้ แต่นิยามฟังก์ชันvirualenvwrapperไม่ทำงานเนื่องจากสคริปต์ไม่สอดคล้องกับ POSIX
สคริปต์ไม่ได้ให้ข้อผิดพลาดใด ๆ แต่จะจบลงโดยไม่มีคำจำกัดความ"workon"
ดังนั้นคุณสามารถตั้งค่าสภาพแวดล้อมได้ใน~ / .profileเพียงเพื่อเปิดใช้งานการดำเนินการ python ที่ถูกต้องจากไคลเอนต์ที่เริ่มต้นโดยตรงจาก X:
export VIRTUAL_ENV="/home/mike/var/virtualenvs/myvirtualenv"
export PATH="$VIRTUAL_ENV/bin:$PATH"
unset PYTHON_HOME
 
     https://gist.github.com/datagrok/2199506
https://www.bountysource.com/issues/9061991-setting-up-your-computer-virtualenvwrapper-linux-all
แต่สำหรับvirualenvwrapperคุณมีสองทางเลือก:
- ซอร์สใน~ / .bash_profileหรือ~ / .zprofile (หรือ ~ / .zlogin) เมื่อเทอร์มินัลทำหน้าที่เป็นล็อกอินเชลล์
 - รวมสคริปต์ใน~ / .bashrcหรือ~ / zshrc
 
ซึ่งหมายความว่าไคลเอนต์ X (เช่น emacs) ควรเริ่มต้นจากเทอร์มินัลเชลล์ไม่ใช่จากกราฟิก!
"ฉันไม่พอใจไม่ได้ ... "