การเลือกระหว่าง. bashrc, .profile, .bash_profile ฯลฯ [ซ้ำกัน]


197

คำถามนี้มีคำตอบอยู่ที่นี่แล้ว:

นี้เป็นที่น่าอาย แต่หลังจากหลายปีของการใช้ระบบ POSIX เต็มเวลาก็ยังมีเวลาที่ยากหาถ้าปรับแต่งเปลือกควรจะไปใน.bashrc, .profileหรือที่อื่น ไม่ต้องพูดถึงบางส่วนของ OS เฉพาะ config .pam_environmentไฟล์เช่น

ใช่ฉันรู้วิธีไขปริศนาผ่านเอกสารและเรียนรู้เมื่อแต่ละไฟล์มีหรือไม่มีการโหลด สิ่งที่ฉันสงสัยคือถ้ามีใครทุกคนรวบรวมแนวทางที่ครอบคลุมสำหรับการตัดสินใจว่าจะเลือกไฟล์ประเภทใดในการปรับแต่งที่กำหนด


6
คำถามนี้ไม่ควรถูกทำเครื่องหมายว่าซ้ำเนื่องจากเหตุผลคือ. profile ไม่สามารถใช้ได้ในคำถามที่เพิ่มเข้ามา
Premraj

คำตอบ:


222

TL; DR:

  • ~/.bash_profileควรง่ายสุด ๆ และเพียงโหลด.profileและ .bashrc(ตามลำดับ)

  • ~/.profileมีเนื้อหาที่ไม่เกี่ยวข้องกับการทุบตีเช่นตัวแปรสภาพแวดล้อม ( PATHและเพื่อน) โดยเฉพาะ

  • ~/.bashrcมีทุกสิ่งที่คุณต้องการในบรรทัดคำสั่งแบบโต้ตอบ พรอมต์คำสั่งEDITORตัวแปรนามแฝงทุบตีสำหรับการใช้งานของฉัน

หมายเหตุอื่น ๆ :

  • สิ่งใดก็ตามที่ควรมีให้สำหรับแอปพลิเคชันกราฟิกหรือ sh (หรือ bash ที่เรียกใช้เป็นsh) ต้องอยู่ใน~/.profile

  • ~/.bashrc ต้องไม่ส่งออกอะไร

  • สิ่งใดก็ตามที่ควรมีให้สำหรับการเข้าสู่ระบบเปลือกเท่านั้นควรเข้าไป ~/.profile

  • รับรองว่า~/.bash_loginไม่มีอยู่จริง


3
+1 นี้ช่วยให้~/.profileการตั้งค่าสภาพแวดล้อมสำหรับบริการเช่น GDM / LightDM / LXDM ซึ่งเรียกใช้อย่างชัดเจน / bin / sh
grawity

12
.bashrcผลลัพธ์ของฉันค่อนข้างเยอะคุณสามารถแสดงความคิดเห็นกับสิ่งนั้นได้ไหม? โดยเฉพาะอย่างยิ่งฉันควรใส่คำทักทายที่ใด
Calimo

14
@Calimo: ทำเฉพาะสิ่งที่ส่งออกในโหมดโต้ตอบ คุณสามารถทดสอบโดยใช้[[ $- == *i* ]]นั่นคือค้นหา 'i' ใน$-ตัวแปรพิเศษ แน่นอนว่ามันเป็นเรื่องสำคัญในสถานที่แรกในระบบที่มีการคอมไพล์ bash ให้อ่าน.bashrcในโหมดที่ไม่มีการโต้ตอบ (นั่นคือ Debian แต่ไม่ใช่ Arch.) แต่เป็นสาเหตุของข้อความแสดงข้อผิดพลาดลึกลับบ่อยครั้งเมื่อพยายามเชื่อมต่อโดยใช้sftpหรือscpหรือเครื่องมือที่คล้ายกัน
grawity

4
ตอนนี้ฉันต้องรู้แล้ว - .bash_login ทำไมจึงไม่มีอยู่? มันทำอะไร?
tedder42

11
@ tedder42: มันไม่เหมือนกันเป็นและ.bash_profile .profileแต่ทุบตีอ่านคนแรกจากสามคนเท่านั้น ความหมายถ้าคุณมี.bash_loginแล้วทั้งสอง.profileและ.bash_profileจะถูกมองข้ามอย่างลึกลับ
grawity

54

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

ความต้องการ:

  • ~/.profile ต้องเข้ากันได้กับ / bin / sh - ซึ่งรวมถึง bash, dash, ksh, ไม่ว่า distro อาจเลือกใช้อะไร

  • ตัวแปรสภาพแวดล้อมจะต้องใส่ในไฟล์ที่อ่านโดยการล็อกอินคอนโซล (เช่นเชลล์ 'ล็อกอิน') และการเข้าสู่ระบบกราฟิก (เช่นผู้จัดการการแสดงผลเช่น GDM, LightDM หรือ LXDM)

  • มีจุดน้อยมากในการมีทั้ง และ~/.profile ~/.bash_profileถ้าหลังจะหายไปทุบตีอย่างมีความสุขจะใช้อดีตและเส้นทุบตีเฉพาะใด ๆ ที่สามารถเตรียมพร้อมกับการตรวจสอบหาหรือ$BASH$BASH_VERSION

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

การกำหนดค่าที่ง่ายที่สุดคือ:

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

    ส่งออก TZ = "ยุโรป / ปารีส"
    export EDITOR = "vim"
    ถ้า ["$ BASH"]; แล้วก็
        . ~ / .bashrc
    Fi
    uptime
    
  • มี~/.bashrcที่ดำเนินการใด ๆ ที่ติดตั้งเปลือกเฉพาะเตรียมพร้อมกับการตรวจสอบสำหรับโหมดโต้ตอบเพื่อหลีกเลี่ยงการทำลายสิ่งที่ต้องการsftpใน Debian (ที่ทุบตีจะรวบรวมกับตัวเลือกในการโหลด~/.bashrcแม้สำหรับเปลือกหอยที่ไม่ใช่แบบโต้ตอบ):

    [[$ - == * i *]] || กลับ 0
    
    PS1 = '\ h \ w \ $'
    
    เริ่มต้น () {sudo service "$ 1" start; }
    

อย่างไรก็ตามยังมีปัญหาที่คำสั่งที่ไม่โต้ตอบบางคำสั่ง (เช่นssh <host> ls) ข้าม~/.profileแต่ตัวแปรสภาพแวดล้อมจะมีประโยชน์มากสำหรับพวกเขา

  • การแจกแจงบางอย่าง (เช่น Debian) รวบรวม bash ของพวกเขาด้วยตัวเลือกแหล่งที่มา~/.bashrcสำหรับการเข้าสู่ระบบที่ไม่ใช่แบบโต้ตอบ ในกรณีนี้ฉันพบว่ามีประโยชน์ในการย้ายตัวแปรสภาพแวดล้อมทั้งหมด ( export ...บรรทัด) ไปยังไฟล์ที่แยกต่างหาก~/.environและแหล่งที่มาจากทั้งสอง .profileและ.bashrcมียามเพื่อหลีกเลี่ยงการทำมันสองครั้ง:

    ถ้า! ["$ PREFIX"]; แล้ว    # หรือ $ EDITOR หรือ $ TZ หรือ 
        ... ~ /. สภาพแวดล้อม            # โดยทั่วไปตัวแปรใด ๆ ที่. สภาพแวดล้อมจะตั้งค่าเอง
    Fi
    
  • น่าเสียดายสำหรับดิสทริบิวชันอื่น ๆ (เช่น Arch) ฉันไม่พบวิธีแก้ปัญหาที่ดีมาก ความเป็นไปได้อย่างหนึ่งคือการใช้โมดูล pam_env PAM (เปิดใช้งานโดยค่าเริ่มต้น) โดยใส่สิ่งต่อไปนี้ใน~/.pam_environment:

    BASH_ENV =. /. environ         # ไม่ใช่ตัวพิมพ์ผิด มันต้องเป็นเส้นทาง แต่ ~ จะไม่ทำงาน
    

    แล้วแน่นอนการปรับปรุงการ~/.environunset BASH_ENV


สรุป? เปลือกหอยเป็นสิ่งที่เจ็บปวด ตัวแปรสภาพแวดล้อมเป็นความเจ็บปวด ตัวเลือกเวลารวบรวมเฉพาะการแจกจ่ายเป็นความเจ็บปวดอันยิ่งใหญ่ในตูด


2
+1 สำหรับวรรคสุดท้าย แต่ฉันชอบการจัดหา.profileและ.bashrcจาก.bash_profileและการรักษาความ.profileสะอาด
nyuszika7h

@ nyuszika7h: ฉัน.profile สะอาดดีขอบคุณ
grawity

1
หมายเหตุความคิดเห็นทุกครั้งที่คุณเปิดหน้าต่างเป็นอีกวิธีหนึ่งในรอบสำหรับ OSX
Mark

1
"มีจุดเล็ก ๆ น้อย ๆ ในการมีทั้งคู่~/.profileและ~/.bash_profile": ฉันไม่พอใจ ดูคำตอบของแดนว่าทำไม
rubenvb

@rubenvb คุณสามารถพูดส่วนที่เกี่ยวข้องได้หรือไม่? ฉันคิดว่ามันเป็นเรื่องดีที่จะมีเพียง.profileและปกป้องbashชิ้นส่วนเฉพาะด้วยเงื่อนไข
เคลวิน

36

มีลักษณะที่นี้โพสต์บล็อกที่ยอดเยี่ยมโดย ShreevatsaR นี่คือสารสกัด แต่ไปที่โพสต์บล็อกซึ่งมีคำอธิบายสำหรับคำเช่น "เชลล์ล็อกอิน" แผนภูมิการไหลและตารางที่คล้ายกันสำหรับ Zsh

สำหรับ Bash พวกเขาทำงานดังนี้ อ่านคอลัมน์ที่เหมาะสม ดำเนินการ A จากนั้น B จากนั้น C และอื่น ๆ B1, B2, B3 หมายถึงดำเนินการเฉพาะไฟล์แรกที่พบ

+----------------+-----------+-----------+------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------+-----------+-----------+------+
|/etc/profile    |   A       |           |      |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc|           |    A      |      |
+----------------+-----------+-----------+------+
|~/.bashrc       |           |    B      |      |
+----------------+-----------+-----------+------+
|~/.bash_profile |   B1      |           |      |
+----------------+-----------+-----------+------+
|~/.bash_login   |   B2      |           |      |
+----------------+-----------+-----------+------+
|~/.profile      |   B3      |           |      |
+----------------+-----------+-----------+------+
|BASH_ENV        |           |           |  A   |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|~/.bash_logout  |    C      |           |      |
+----------------+-----------+-----------+------+

นี่เป็นสิ่งที่ดี มันเป็นสิ่งสำคัญที่จะทราบว่ามักจะ/etc/profileเรียกร้อง/etc/bash.bashrcและการโทร~/.profile ~.bashrcอย่างมีประสิทธิภาพ/etc/bash.bashrcและ~/.bashrcกำลังดำเนินการสำหรับการเข้าสู่ระบบแบบโต้ตอบเช่นกัน
wisbucky

โปรดทราบว่าการแจกแจงบางอย่างดูเหมือนจะแทนที่โครงร่างนี้ (โดยมีผลกระทบที่แปลกประหลาด) - ดูเช่นข้อผิดพลาดของฉันเพื่อเปิดใช้งานที่นี่: bugzilla.opensuse.org/show_bug.cgi?id=1078124
Christian Herenz

Btw อย่างน้อยด้วยการทุบตีไม่มีไฟล์เหล่านี้จะถูกดำเนินการเมื่อทุบตีจะถูกเรียกผ่าน/bin/sh
JepZ

@JepZ คุณพูดถูกนั่นเป็นสิ่งที่คอลัมน์ที่สาม "สคริปต์" อธิบาย
Flimm

1
@Flimm ดีคอลัมน์ 'Script' อธิบายสิ่งที่เกิดขึ้นเมื่อคุณเริ่มสคริปต์ที่ไม่โต้ตอบผ่านbash (เช่น / bin / bash) อย่างไรก็ตามหากคุณเริ่มต้นสคริปต์ผ่านsh (และ / bin / sh เป็น symlink ไปยัง / bin / bash) ไม่มีการดำเนินการใด ๆ ข้างต้น (ไม่เท่ากันBASH_ENV) If bash is invoked with the name shย่อหน้าที่เกี่ยวข้องของหน้าคนทุบตีสามารถพบได้โดยการค้นหา
JepZ

21

ฉันเสนอแนวทาง "แบบครอบคลุม" ให้กับคุณ:

  • ทำ.bash_profileและ.profileโหลด.bashrcหากมีอยู่โดยใช้เช่น [ -r $HOME/.bashrc ] && source $HOME/.bashrc
  • .bashrcใส่ทุกอย่างอื่นใน
  • หยุดกังวล.
  • ทุกสี่ปีหรือมากกว่านั้นใช้เวลาสิบนาทีค้นคว้าคำถามนี้ก่อนที่จะยอมแพ้และกลับไปที่ "ไม่ต้องกังวล"

แก้ไข: เพิ่มคำพูดที่ทำให้หวาดกลัวเป็น "แบบครอบคลุม" ในกรณีที่ใครก็ตามไม่อยากเชื่อ ;)


3
มีทั้ง.bash_profileและ.profileเป็นบิตซ้ำซ้อน; คุณต้องการหลังเท่านั้น คุณจำเป็นต้องสร้างมัน / bin / sh-proof แม้ว่า: if [ "$BASH" ] && [ -r ~/.bashrc ]; then . ~/.bashrc; fiเนื่องจากมีโปรแกรม (คือ gdm / lightdm) ที่แหล่งไฟล์ด้วยตนเองจากสคริปต์ / bin / sh นี่ก็หมายความว่าสภาพแวดล้อมที่เก็บไว้ใน.bashrcนั้นจะไม่ได้ผล ต้องใช้ -1 เนื่องจากแนวทาง "ที่ครอบคลุม" ของคุณจะไม่สามารถใช้ได้กับหลาย ๆ ระบบอย่างที่ฉันได้พบมาแล้วหลายครั้ง
grawity

ไม่มีปัญหาฉันยินดีจ่าย -1 สำหรับคำตอบที่ไม่ได้เป็นเพียงแค่ลิ้น "แก้ม" ที่ครอบคลุมและคุณได้รับตำแหน่งนั้นอย่างแน่นอน
ปลากล

0

ฉันยอมแพ้ในการพยายามคิดออกและทำหนึ่งสคริปต์ ( ~/.shell-setup) ซึ่งฉันมาจากคนอื่นทั้งหมด

วิธีนี้ต้อง~/.shell-setupมีคุณสมบัติสองอย่าง:

  1. เรียกใช้เพียงครั้งเดียวแม้เมื่อมีการจัดหาซ้ำ ๆ (ใช้Include guards )
  2. อย่าสร้างเอาท์พุทที่ไม่ต้องการ (ตรวจจับเมื่อเอาต์พุตไม่เป็นไร)

# 1 เป็นมาตรฐานสวยแม้ว่าอาจจะไม่ค่อยได้ใช้ในเชลล์สคริปต์

# 2 มีเล่ห์เหลี่ยม นี่คือสิ่งที่ฉันใช้ในทุบตี:

if [ "" == "$BASH_EXECUTION_STRING" -a "" == "$DESKTOP_SESSION" ]; then
    echo "Hello user!" # ... etc
fi

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


-2

ใส่ทุกอย่างใน.bashrcนั้นที่มา.bashrcจาก.profile

จากหน้า bash man (บน OS X 10.9):

เมื่อเชลล์เชิงโต้ตอบที่ไม่ใช่เชลล์ล็อกอินเริ่มทำงาน bash จะอ่านและดำเนินการคำสั่งจาก ~ / .bashrc หากไฟล์นั้นมีอยู่ สิ่งนี้อาจถูกยับยั้งโดยใช้ตัวเลือก --norc ตัวเลือกไฟล์ --rcfile จะบังคับให้ทุบตีเพื่ออ่านและดำเนินการคำสั่งจากไฟล์แทน ~ / .bashrc

.bashrcข้อความข้างต้นคือเหตุผลที่ทุกอย่างจะใส่ใน อย่างไรก็ตามมีพฤติกรรมแตกต่างกันเล็กน้อยเมื่อคุณจัดการกับเชลล์การเข้าสู่ระบบ อีกครั้งข้อความจากหน้าคน:

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

.profileถูกอ่านสำหรับล็อกอินเชลล์ แต่.bashrcไม่ใช่ การทำซ้ำสิ่งที่อยู่ใน.bashrcนั้นไม่ดี™ดังนั้นเราจึงต้องจัดหาแหล่งข้อมูล.profileเพื่อให้พฤติกรรมยังคงสอดคล้องกัน

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


4
-1, DO NOTแหล่งที่มาจาก.bashrc .profileดูคำตอบของ @ DanRabinowitz
nyuszika7h

อย่างน้อยก็ไม่มีเงื่อนไข
nyuszika7h

[ -n "$BASH" -a -f ~/.bashrc ] && . ~/.bashrcจะเป็น oneliner .profileหวานสำหรับ
John WH Smith

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