ความแตกต่างระหว่าง. bashrc และ. bash_profile

Sep 02 2010

อะไรคือความแตกต่างระหว่าง.bashrcและ.bash_profileและเป็นที่หนึ่งฉันควรใช้?

คำตอบ

567 Gilles'SO-stopbeingevil' Sep 03 2010 at 02:23

ตามเนื้อผ้าเมื่อคุณเข้าสู่ระบบ Unix ระบบจะเริ่มโปรแกรมหนึ่งโปรแกรมให้คุณ โปรแกรมนั้นคือเชลล์กล่าวคือโปรแกรมที่ออกแบบมาเพื่อเริ่มโปรแกรมอื่น ๆ มันเป็นเชลล์บรรทัดคำสั่ง: คุณเริ่มโปรแกรมอื่นโดยพิมพ์ชื่อ เชลล์ดีฟอลต์ซึ่งเป็นเชลล์เป้าหมายอ่านคำสั่ง~/.profileเมื่อเรียกใช้เป็นเชลล์ล็อกอิน

Bash เป็นเปลือกที่มีลักษณะคล้ายบอร์น มันอ่านคำสั่ง~/.bash_profileเมื่อเรียกใช้เป็นเชลล์ล็อกอินและหากไม่มีไฟล์นั้น¹ระบบจะลองอ่าน~/.profileแทน

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

ดังนั้น:

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

  • ~/.bashrcเป็นสถานที่สำหรับใส่สิ่งที่ใช้กับ bash เท่านั้นเช่นนามแฝงและคำจำกัดความของฟังก์ชันตัวเลือกเชลล์และการตั้งค่าพร้อมต์ (คุณสามารถใส่การผูกคีย์ที่นั่นได้ แต่สำหรับการทุบตีพวกเขามักจะเข้า~/.inputrc)

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

    if [ -r ~/.profile ]; then . ~/.profile; fi
    case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
    

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

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

¹ เพื่อความสมบูรณ์ตามคำขอ: ถ้า.bash_profileไม่ได้อยู่ทุบตียังพยายามก่อนที่จะล้มกลับไป.bash_login .profileอย่าลังเลที่จะลืมมันมีอยู่

58 Jarvin Sep 02 2010 at 21:54

จากบทความสั้น ๆ นี้

ตามหน้า bash man จะเรียกใช้. bash_profile สำหรับล็อกอินเชลล์ในขณะที่. bashrc ถูกเรียกใช้สำหรับเชลล์ที่ไม่ใช่ล็อกอินแบบโต้ตอบ

เชลล์ล็อกอินหรือไม่ล็อกอินคืออะไร?

เมื่อคุณเข้าสู่ระบบ (เช่น: พิมพ์ชื่อผู้ใช้และรหัสผ่าน) ผ่านคอนโซลไม่ว่าจะนั่งอยู่ที่เครื่องเมื่อทำการบูทหรือจากระยะไกลผ่าน ssh: .bash_profile จะถูกดำเนินการเพื่อกำหนดค่าสิ่งต่างๆก่อนพร้อมต์คำสั่งเริ่มต้น

แต่ถ้าคุณได้ล็อกอินเข้าเครื่องของคุณแล้วและเปิดหน้าต่างเทอร์มินัลใหม่ (xterm) ภายใน Gnome หรือ KDE ระบบจะดำเนินการ. bashrc ก่อนพรอมต์คำสั่งของหน้าต่าง .bashrc ยังทำงานเมื่อคุณเริ่มอินสแตนซ์ bash ใหม่โดยพิมพ์ / bin / bash ในเทอร์มินัล

40 RichHomolka Sep 03 2010 at 01:10

ย้อนกลับไปในสมัยก่อนเมื่อ pseudo tty ไม่ใช่ของปลอม แต่จริงๆแล้วโมเด็มก็ถูกพิมพ์และ UNIXes เข้ามาช้ามากจนคุณสามารถเห็นตัวอักษรแต่ละตัวถูกพิมพ์ลงบนหน้าจอของคุณประสิทธิภาพเป็นสิ่งสำคัญยิ่ง เพื่อช่วยเพิ่มประสิทธิภาพคุณมีแนวคิดเกี่ยวกับหน้าต่างการเข้าสู่ระบบหลักและหน้าต่างอื่น ๆ ที่คุณใช้ในการทำงานจริง ในหน้าต่างหลักของคุณคุณต้องการให้มีการแจ้งเตือนไปยังเมลใหม่โดยอาจเรียกใช้โปรแกรมอื่น ๆ ในพื้นหลัง

เพื่อสนับสนุนสิ่งนี้เชลล์จัดหาไฟล์.profileโดยเฉพาะจาก 'ล็อกอินเชลล์' สิ่งนี้จะทำแบบพิเศษเมื่อตั้งค่าเซสชัน Bash ขยายสิ่งนี้ให้ดูที่. bash_profile ก่อน. profile ด้วยวิธีนี้คุณสามารถใส่ bash เฉพาะสิ่งต่างๆไว้ในนั้นได้ (ดังนั้นพวกเขาจะไม่ทำให้ Bourne shell เสียหาย ฯลฯ ซึ่งดูที่. profile ด้วย) เชลล์อื่น ๆ ที่ไม่ใช่ล็อกอินจะเป็นเพียงแค่ซอร์สไฟล์ rc, .bashrc (หรือ. shrc ฯลฯ )

นี่เป็นความล้าสมัยเล็กน้อยในตอนนี้ คุณไม่ได้เข้าสู่เชลล์หลักมากเท่าที่คุณลงชื่อเข้าใช้ตัวจัดการหน้าต่าง gui ไม่มีหน้าต่างหลักใดที่แตกต่างไปจากหน้าต่างอื่น ๆ

ข้อเสนอแนะของฉัน - ไม่ต้องกังวลกับความแตกต่างนี้ขึ้นอยู่กับรูปแบบเก่าของการใช้ยูนิกซ์ ขจัดความแตกต่างในไฟล์ของคุณ เนื้อหาทั้งหมดของ. bash_profile ควรเป็น:

[ -f $HOME/.bashrc ] && . $HOME/.bashrc

และใส่ทุกสิ่งที่คุณต้องการตั้งค่าใน. bashrc

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

[[ $- != *i* ]] && return

20 Flimm Jul 13 2016 at 15:53

มีลักษณะที่นี้โพสต์บล็อกที่ยอดเยี่ยมโดย ShreevatsaR นี่คือสารสกัด แต่ไปที่บล็อกโพสต์จะมีคำอธิบายสำหรับคำต่างๆเช่น "login shell" ผังงานและตารางที่คล้ายกันสำหรับ 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      |           |      |
+----------------+-----------+-----------+------+
7 Ellipticalview Oct 19 2016 at 01:13

ความคิดเห็นที่ดีกว่าสำหรับหัว / ETC / โปรไฟล์

อาคารในคำตอบที่ดี Flimm ของข้างต้นผมแทรกนี้ความเห็นใหม่ที่หัวของ Debian ของฉัน/etc/profile, (คุณอาจจำเป็นต้องปรับมันสำหรับ distro คุณ.) :

# For BASH: Read down the appropriate column. Executes A, then B, then C, etc.
# The B1, B2, B3 means it executes only the first of those files found.  (A)
# or (B2) means it is normally sourced by (read by and included in) the
# primary file, in this case A or B2.
#
# +---------------------------------+-------+-----+------------+
# |                                 | Interactive | non-Inter. |
# +---------------------------------+-------+-----+------------+
# |                                 | login |    non-login     |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   ALL USERS:                    |       |     |            |
# +---------------------------------+-------+-----+------------+
# |BASH_ENV                         |       |     |     A      | not interactive or login
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile                     |   A   |     |            | set PATH & PS1, & call following:
# +---------------------------------+-------+-----+------------+
# |/etc/bash.bashrc                 |  (A)  |  A  |            | Better PS1 + command-not-found 
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/bash_completion.sh|  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/vte-2.91.sh       |  (A)  |     |            | Virt. Terminal Emulator
# |/etc/profile.d/vte.sh            |  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   A SPECIFIC USER:              |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_profile    (bash only)   |   B1  |     |            | (doesn't currently exist) 
# +---------------------------------+-------+-----+------------+
# |~/.bash_login      (bash only)   |   B2  |     |            | (didn't exist) **
# +---------------------------------+-------+-----+------------+
# |~/.profile         (all shells)  |   B3  |     |            | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bashrc          (bash only)   |  (B2) |  B  |            | colorizes bash: su=red, other_users=green
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_logout                   |    C  |     |            |
# +---------------------------------+-------+-----+------------+
#
# ** (sources !/.bashrc to colorize login, for when booting into non-gui)

และหมายเหตุนี้ที่ส่วนหัวของไฟล์ติดตั้งอื่น ๆ เพื่ออ้างถึง:

# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE

ที่น่าสังเกตฉันคิดว่า Debian เป็น/etc/profileแหล่งที่มาเริ่มต้น (รวมถึง) /etc/bash.bashrc(นั่นคือเมื่อ/etc/bash.bashrcมีอยู่) ดังนั้นสคริปต์การเข้าสู่ระบบจะอ่านทั้งสอง/etcไฟล์ในขณะที่ไม่ใช่ล็อกอินอ่านเฉพาะ bash.bashrc

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

5 MarcH Jun 25 2019 at 05:55

ตรรกะการกำหนดค่าของ bash นั้นไม่ซับซ้อนและอธิบายไว้ในคำตอบอื่น ๆ ในหน้านี้บนเซิร์ฟเวอร์ผิดพลาดและในหลาย ๆ บล็อก อย่างไรก็ตามปัญหาคือสิ่งที่การกระจาย Linux ทำจาก bashฉันหมายถึงวิธีที่ซับซ้อนและหลากหลายที่พวกเขากำหนดค่า bash ตามค่าเริ่มต้นhttp://mywiki.wooledge.org/DotFilesกล่าวถึงนิสัยใจคอเหล่านี้สั้น ๆ ต่อไปนี้เป็นตัวอย่างการติดตามบน Fedora 29 ซึ่งจะแสดงว่าไฟล์ใดเป็นแหล่งที่มาซึ่งไฟล์อื่นและลำดับสำหรับสถานการณ์ที่ง่ายมาก: เชื่อมต่อจากระยะไกลกับ ssh จากนั้นเริ่มต้น subshell อื่น:

ssh fedora29
 └─ -bash # login shell
      ├── /etc/profile
      |    ├─ /etc/profile.d/*.sh
      |    ├─ /etc/profile.d/sh.local
      |    └─ /etc/bashrc
      ├── ~/.bash_profile
      |    └─ ~/.bashrc
      |          └─ /etc/bashrc
      |
      |
      └─ $ bash  # non-login shell
            └─ ~/.bashrc
                 └─ /etc/bashrc
                       └─ /etc/profile.d/*.sh

ตรรกะที่ซับซ้อนที่สุดของ Fedora อยู่ใน/etc/bashrc. ดังที่เห็นด้านบน/etc/bashrcคือไฟล์ทุบตีที่ตัวเองไม่รู้ฉันหมายความว่าไม่โดยตรง Fedora /etc/bashrcทดสอบว่า:

  • มันมาจากเชลล์ล็อกอิน
  • มีที่มาจากเชลล์แบบโต้ตอบ
  • มีที่มาแล้ว

... แล้วทำสิ่งที่แตกต่างอย่างสิ้นเชิงขึ้นอยู่กับสิ่งเหล่านั้น

หากคุณคิดว่าสามารถจำกราฟด้านบนได้ก็แย่แล้วเพราะมันยังไม่เพียงพอ: กราฟนี้อธิบายสถานการณ์เพียงสถานการณ์เดียวสิ่งที่แตกต่างกันเล็กน้อยจะเกิดขึ้นเมื่อเรียกใช้สคริปต์ที่ไม่โต้ตอบหรือเริ่มเซสชันกราฟิก ~/.profileผมเคยมองข้าม ฉันได้ละเว้นbash_completionสคริปต์ ด้วยเหตุผลด้านความเข้ากันได้ย้อนหลังให้เรียกใช้ bash /bin/shแทน/bin/bashการเปลี่ยนแปลงพฤติกรรม แล้ว zsh กับเชลล์อื่น ๆ ล่ะ? และแน่นอนว่าลินุกซ์ดิสทริบิวชันที่แตกต่างกันทำสิ่งที่แตกต่างกันเช่นDebian และ Ubuntu มาพร้อมกับ bas h เวอร์ชันที่ไม่ได้มาตรฐานแต่ก็มีการปรับแต่งเฉพาะ Debian โดยเฉพาะอย่างยิ่งมองหาไฟล์ที่ผิดปกติ: /etc/bash.bashrc. แม้ว่าคุณจะยึดติดกับการแจกจ่าย Linux เพียงเครื่องเดียว แต่ก็อาจพัฒนาไปตามกาลเวลา เดี๋ยวก่อน: เรายังไม่เคยสัมผัส macOS, FreeBSD, ... ในที่สุดเรามาลองคิดดูสำหรับผู้ใช้ที่ติดอยู่กับวิธีที่สร้างสรรค์ยิ่งขึ้นที่ผู้ดูแลระบบของพวกเขากำหนดค่าระบบที่พวกเขาต้องใช้

เนื่องจากกระแสการอภิปรายที่ไม่สิ้นสุดในหัวข้อนี้แสดงให้เห็นว่ามันเป็นสาเหตุที่หายไป ตราบใดที่คุณต้องการเพิ่มค่าใหม่ "การลองผิดลองถูก" บางอย่างก็น่าจะเพียงพอแล้ว ความสนุกที่แท้จริงเริ่มต้นเมื่อคุณต้องการแก้ไขในไฟล์ (ผู้ใช้) หนึ่งไฟล์ที่กำหนดไว้แล้วในอีกไฟล์หนึ่ง (ใน / etc) จากนั้นเตรียมพร้อมที่จะใช้เวลาในการวิศวกรรมโซลูชันที่ไม่มีวันพกพาได้

เพื่อความสนุกสุดท้ายนี่คือ "กราฟแหล่งที่มา" สำหรับสถานการณ์ง่ายๆเดียวกันบน Clear Linux ณ เดือนมิถุนายน 2019:

ssh clearlinux
 └─ -bash # login shell
      ├── /usr/share/defaults/etc/profile
      |    ├─ /usr/share/defaults/etc/profile.d/*
      |    ├─ /etc/profile.d/*
      |    └─ /etc/profile
      ├── ~/.bash_profile
      |
      |
      └─  $ bash   # non-login shell
           ├─ /usr/share/defaults/etc/bash.bashrc
           |      ├─ /usr/share/defaults/etc/profile
           |      |    ├─ /usr/share/defaults/etc/profile.d/*
           |      |    ├─ /etc/profile.d/*
           |      |    └─ /etc/profile
           |      └─ /etc/profile
           └─ ~/.bashrc