ตัวแปรสภาวะแวดล้อมใน bash_profile หรือ bashrc?


35

ฉันพบคำถามนี้ [บล็อก]: ความแตกต่างระหว่าง. bashrc และ. bash_profileมีประโยชน์มาก แต่หลังจากเห็นคำตอบที่ได้รับการโหวตมากที่สุด (ดีมากโดยวิธีการ) ฉันมีคำถามเพิ่มเติม ในตอนท้ายของการโหวตมากที่สุดคำตอบที่ถูกต้องฉันเห็นข้อความดังต่อไปนี้:

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

  1. ทำไมมันเป็นความคิดที่ไม่ดี (ฉันไม่ได้พยายามจะต่อสู้ฉันแค่อยากจะเข้าใจ)?

  2. หากฉันต้องการตั้งค่าตัวแปรสภาพแวดล้อมและเพิ่มลงใน PATH (เช่น JAVA_HOME) ซึ่งเป็นสถานที่ที่ดีที่สุดในการใส่รายการส่งออก ใน~ / .bash_profileหรือ~ / .bashrc ?

  3. หากคำตอบของคำถามหมายเลข 2 คือ~ / .bash_profile แสดงว่าฉันมีคำถามอีกสองข้อ:

    3.1 สิ่งที่คุณจะวางภายใต้~ / .bashrc ? นามแฝงเท่านั้น

    3.2 ในเชลล์ที่ไม่ใช่การเข้าสู่ระบบฉันเชื่อว่า~ / .bash_profileไม่ได้ถูก "หยิบขึ้นมา" หากการส่งออกรายการ JAVA_HOME อยู่ใน bash_profile ฉันจะสามารถดำเนินการคำสั่งjavac & java ได้หรือไม่ มันจะพบพวกเขาบนเส้นทางหรือไม่? นั่นเป็นเหตุผลที่โพสต์และฟอรัมบางข้อแนะนำให้ตั้ง JAVA_HOME และเหมือนกันกับ~ / .bashrc ?

    ขอบคุณล่วงหน้า.

คำตอบ:


25

ในระบบที่ทันสมัยมันไม่ได้เป็นเรื่องธรรมดาโดยเฉพาะอย่างยิ่งในกรณีที่มันมีความสำคัญ แต่มันเกิดขึ้น (โดยเฉพาะถ้าคุณใช้การทำงานของเชลล์ใน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ทำงานโดยรูตเชลล์) ก่อนที่จะพยายามใช้สภาพแวดล้อมเหล่านั้นก็ไม่มีปัญหา เมื่อเริ่มใช้งานพวกเขาสับสนกับการสูญเสียการตั้งค่าที่ไม่คาดคิด


1
ฉันคิดว่าฉันเข้าใจฉันอาจต้องอ่านอีกครั้งเพื่อทำให้เป็นภายในมากขึ้น แต่ฉันกำลังสรุปต่อไปนี้ ในสภาพแวดล้อมขององค์กรเพื่อให้มีการควบคุมปลีกย่อยของเปลือกหอยที่กำหนดเองโดยไม่ต้องมีผลข้างเคียงของคนทั่วโลกมันเป็นวิธีที่ดีที่สุดที่จะนำตัวแปรสภาพแวดล้อมใน~ / .bash_profile ในสภาพแวดล้อมส่วนบุคคลเช่น Ubuntu หรือ Linux Mint เพื่อให้มีการตั้งค่า PATH อย่างถูกต้องฉันควรตั้งค่าภายใต้~ / .bashrc (หรือแม้แต่ใน/ etc / profile ) ฉันถูกไหม?
Viriato

มีน้อยที่จะทำกับสภาพแวดล้อมขององค์กรกว่าว่าคุณเป็นเพียงผู้ใช้หรือนักพัฒนา; ระบบที่ต้องการmodulesและrvmเป็นเครื่องมือสำหรับนักพัฒนาเช่นเดียวกับ Matlab และ Cadence สำหรับคำจำกัดความที่แตกต่างกันของ "นักพัฒนา" การพัฒนาแบบธรรมดายังไม่จำเป็นต้องพวกเขา แต่เมื่อคุณจำเป็นต้องทดสอบกับหลายรุ่นของทับทิม, Perl, Python หรือจริงๆแล้วคุณต้องการสิ่งที่ต้องการrvm, perlbrewและvirtualenv(ตามลำดับ) ไปรอบ ๆ เพื่อช่วยให้มันทั้งหมดตรง
geekosaur

2

เพื่อความซื่อสัตย์มีความแตกต่างกันเล็กน้อยในวันนี้แม้จะมีสิ่งที่กูรูต้องพูด

ปัญหาที่อยู่เบื้องหลังนี้คือทุกวันนี้เราเข้าสู่ระบบแบบกราฟิกมากกว่าผ่านเชลล์การเข้าสู่ระบบ ในอดีตเรา unix ผู้ใช้ต้องการดูรายงานสั้น ๆ ว่าเกิดอะไรขึ้นบนเซิร์ฟเวอร์ทันทีหลังจากเข้าสู่ระบบ - จากนั้นเราจะเริ่มต้น X ตามบรรทัดคำสั่ง - รายงานเหล่านี้มักจะต้องใช้เวลาในการสร้าง (เช่น 10-20 วินาที) และจากนั้นเราไม่ต้องการเห็นสิ่งเดียวกันเมื่อเราเริ่มต้นเช่น xterm ดังนั้นความแตกต่าง

ทุกวันนี้ฉันไม่คิดว่าความแตกต่างสำคัญเท่าไหร่ในตอนนี้ ฉันคิดว่าวันนี้ถ้าคุณมา bashrc ใน bash_profile ไม่มีใครสามารถตำหนิคุณ

โปรดทราบว่าสิ่งนี้ใช้ไม่ได้กับ macos x (ทุก terminal.app ที่เริ่มต้นคือเชลล์ล็อกอิน)


ฉันไม่แน่ใจว่าฉันเข้าใจอย่างถ่องแท้ แต่ในที่ทำงานเมื่อฉันลงชื่อเข้าใช้ผ่าน ssh นั่นคือเชลล์การล็อกอินจากนั้น bash_profile และ bashrc จะได้รับที่มาดังนั้นฉันเดาว่ามันไม่สำคัญ แต่ถ้าฉันเข้าสู่ระบบแบบกราฟิก (หมายความว่าอะไร) ชอบเข้าสู่ระบบอูบุนตูส่วนตัวของฉัน?
Viriato

เห็นด้วยกับคำตอบ @bubu ที่นี่ - การตั้งค่าใด ๆ ที่~/.bash_profileไม่มีแหล่งที่มา~/.bashrcค่อนข้างยากที่จะทำงานกับและ verging ที่แตก แอปเทอร์มินัลแบบกราฟิกหมายความว่าง่ายกว่าที่จะเพียงแค่แหล่ง ~ / .bashrc และวางการตั้งค่าทั้งหมดไว้ในนั้น
RichVel

1

เกี่ยวกับ "การเข้าสู่ระบบแบบกราฟิก" ขึ้นอยู่กับ * 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

มีสองกรณี

  1. / bin / shเชื่อมโยงกับ/ bin / bashแต่ทำงานในโหมด "POSIX / Bourne"
  2. / bin / sh is / bin / dash (debian / ubuntu) เร็วที่สุด แต่มีคุณสมบัติน้อยกว่า(สนับสนุน ShellShock;) )

ดังนั้นโปรไฟล์ / bin / sh จึงเป็น~ / .profileและไม่ใช่ ~ / .bash_profile, ~ / .zprofile

ไฟล์นี้ควรใช้สำหรับการตั้งค่า"ผู้ไม่เชื่อเรื่องเชลล์"เช่นเส้นทางและตัวแปรสภาพแวดล้อม

ไม่มีโปรแกรมที่ปฏิบัติการได้สำหรับการโต้ตอบกับผู้ใช้ที่ลงชื่อเข้าใช้เท่านั้นควรจะอยู่ที่นี่ (การตรวจสอบจดหมายโชคลาภและอื่น ๆ ... )

~ /.* rc มีความหมายสำหรับเซสชัน "โต้ตอบ" เท่านั้น (นามแฝงเช่น ... )

มีความแตกต่างระหว่าง bash และ zsh สำหรับเชลล์ล็อกอินแบบโต้ตอบ

bash ซอร์สเท่านั้น. bash_profile ขณะที่ zsh ซอร์สตามลำดับ:

  1. ~ / .zprofile
  2. ~ / .zshrc
  3. ~ / 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 "ดั้งเดิม" (การส่งออก BASH_VERSION)

หากคุณอยู่ในระบบเส้นประตัวแปรสภาพแวดล้อมและการตั้งค่าเส้นทางจะทำงานได้ แต่การกำหนดฟังก์ชั่นvirualenvwrapperไม่ทำงานเนื่องจากสคริปต์ไม่สอดคล้องกับ POSIX

สคริปต์ไม่ได้ให้ข้อผิดพลาดใด ๆ แต่จะสิ้นสุดโดยไม่มีคำจำกัดความ"workon"

ดังนั้นคุณสามารถตั้งค่าสภาพแวดล้อมที่อยู่ใน~ / .profileเพียงเพื่อเปิดใช้งานการดำเนินการหลามที่ถูกต้องจากไคลเอนต์เริ่มต้นโดยตรงจาก 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คุณมีสองทางเลือก:

  1. หาแหล่งมาใน~ / .bash_profileหรือ~ / .zprofile (หรือ ~ / .zlogin) เมื่อเทอร์มินัลทำหน้าที่เป็นล็อกอินเชลล์
  2. รวมสคริปต์ใน~ / .bashrcหรือ~ / zshrc

ซึ่งหมายความว่าไคลเอนต์ X (เช่น emacs) ควรเริ่มต้นจากเทอร์มินัลเชลล์และไม่ใช่จากกราฟิกหนึ่ง!

"ฉันไม่สามารถรับความพึงพอใจไม่ได้ ... "


เรื่องราวที่แตกต่างกันอย่างสมบูรณ์กำลังเรียกใช้บริการกับsystemd ทางเลือกที่เป็นไปได้บางอย่างคือ: การเขียนสคริปต์wrapperกำหนดสภาพแวดล้อมในไฟล์คำจำกัดความ"บริการ" การทิ้งสภาพแวดล้อมในไฟล์"env"เพื่อให้ได้มาในเปลือกหลัก สิ่งที่จะกลายเป็น trickier กับ RVM / virtualenv ...
hute37
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.