ubuntu下關於profile和bashrc中環境變數的理解,ubuntubashrc

來源:互聯網
上載者:User

ubuntu下關於profile和bashrc中環境變數的理解,ubuntubashrc

(0) 寫在前面

有些名詞可能需要解釋一下。(也可以先不看這一節,在後面看到有疑惑再上來看相關解釋)

$PS1和互動式運行(running interactively): 簡單地來說,互動式運行就是在終端上輸入指令運行,非互動式運行就是執行sh檔案。互動式啟動並執行時候echo $PS1會輸出一長串字元,非互動式運行echo $PS1會輸出#或$,,$代表普通使用者,#代表root。非互動式運行是不會執行bashrc檔案的配置內容的,這點需要注意一下,因為平常都在終端上執行指令,很容易忽略這一點:在bashrc中配置的東西,在執行sh檔案的時候就失效了。

啟動bash shell:就是啟動一個bash shell進程,通常可以理解為開啟一個終端。需要注意的是如果你在終端輸入sh後會發現自己又進入另一個shell命令列(注意這不是互動式運行,可以echo $PS1驗證),這個時候其實fork了一個shell 子進程(會複製一份原終端shell進程的全域變數),如果你在這個shell命令列又輸入了一次sh,那麼相當於fork的shell子進程又fork了一個shell子進程,這個時候就啟動了三個bash shell進程。

輸入exit或者ctrl-d可以退出當前shell,這裡需要連續exit兩次才可以回到原來的終端shell進程(這個時候就變回一個shell進程了)。

source profile或source bashrc:source一個sh檔案,就是把sh檔案的內容載入到本shell環境中執行。可以理解為:執行sh是非互動式運行;在終端source sh檔案,相當於在終端執行sh檔案的指令,就是互動式運行了。

 

(1) profile和bashrc

配置環境變數一般在這兩種檔案中。先講講什麼時候執行,後面再介紹這兩種檔案做了什麼。

profile在系統登入後執行,只在登入系統時執行一次,包括針對系統的/etc/profile針對使用者的~/.profile。

bashrc在每次啟動bash shell(開啟終端或者在終端輸入sh)後執行,包括針對系統的/etc/bash.bashrc針對使用者的~/.bashrc(這裡注意一下我的ubuntu裡是/etc/bash.bashrc,其它系統可能是/etc/bashrc)

cat /etc/profilecat /etc/bash.bashrccat ~/.profilecat ~/.bashrc

 

(2) 環境變數

因為要配置環境變數,所以要對環境變數有所瞭解。shell中的環境變數分為全域變數和局部變數。

blogger="piligrimHui"  這樣定義的為局部變數export blogger="pilgrimHui" 這樣定義的為全域變數(export這個變數,則升級為全域變數)

 

2.1 局部變數:父進程定義的局部變數,子進程無法訪問;子進程定義的局部變數,父進程無法訪問。

# parent.sh#!/bin/bashpid="parent"sh child.shecho "父shell訪問子shell的cid:$cid"
# child.sh#!/bin/bashecho "子shell訪問父shell的pid:$pid"cid="child"
sh parent.sh子shell訪問父shell的pid:父shell訪問子shell的cid:

 

2.2 全域變數:父shell定義的全域變數,子shell自身會複製一份父shell的全域變數,所以子shell對全域變數的操作不影響父shell的全域變數。子shell定義的全域變數,父shell不可用。

# parent.sh#!/bin/bashexport name="parent"echo "父shell的name:$name"sh child.shecho "子shell修改name之後,父shell的name:$name"echo "父shell訪問子shell定義的nickName:$nickName"
# child.sh#!/bin/bashecho "子shell的name:$name"name="child"echo "子shell修改name後,子shell的name:$name"nickName="baby"
sh parent.sh父shell的name:parent子shell的name:parent子shell修改name後,子shell的name:child子shell修改name之後,父shell的name:parent父shell訪問子shell定義的nickName:

 

(3) profile做了什麼

登入shell隨著使用者的登入而啟動,可以看作是第一個shell,後續的shell都是登入shell的子shell。

登入shell會執行針對系統的/etc/profile針對使用者的~/.profile。為了讓環境變數在後續的所有shell都能訪問到,可以在這裡配置全域的環境變數,但是注意profile只會在登入的時候執行一次,所以一般配置完後需要重新登入才會生效。(雖然可以自行source profile但是只在當前shell進程有效,這裡的shell進程可以理解為在一個終端裡,但是如果在終端裡輸入sh其實相當於開了兩個shell進程,一個父進程一個子進程)

對於/etc/profile,首先會檢查是否互動式運行(即$PS1不為空白),如果不是則給PS1賦’#‘或'$','#'代表root使用者,'$'代表普通使用者。如果是互動式運行還要是否啟動了bash shell,如果是則執行/etc/bash.bashrc對bash進行相關配置。然後會執行/etc/profile.d目錄下的shell檔案,有一些作為自啟動程式,有些用來定義一些全域環境變數。

對於~/.profile,首先檢查是否啟動了bash shell,如果是則執行~/.bashrc對bash進行相關配置。然後重新設定了PATH(所以導致不同使用者的環境變數PATH不一樣)。

# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).if [ "$PS1" ]; then  if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then    # The file bash.bashrc already sets the default PS1.    # PS1='\h:\w\$ '    if [ -f /etc/bash.bashrc ]; then      . /etc/bash.bashrc    fi  else    if [ "`id -u`" -eq 0 ]; then      PS1='# '    else      PS1='$ '    fi  fifiif [ -d /etc/profile.d ]; then  for i in /etc/profile.d/*.sh; do    if [ -r $i ]; then      . $i    fi  done  unset ifi
# ~/.profile: executed by the command interpreter for login shells.# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login# exists.# see /usr/share/doc/bash/examples/startup-files for examples.# the files are located in the bash-doc package.# the default umask is set in /etc/profile; for setting the umask# for ssh logins, install and configure the libpam-umask package.#umask 022# if running bashif [ -n "$BASH_VERSION" ]; then    # include .bashrc if it exists    if [ -f "$HOME/.bashrc" ]; then    . "$HOME/.bashrc"    fifi# set PATH so it includes user's private bin directoriesPATH="$HOME/bin:$HOME/.local/bin:$PATH"

 

(4) bashrc做了什麼

當啟動bash shell(開啟終端)的時候會執行/etc/bash.bashrc和~/.bashrc。

在執行/etc/profile和~/.profile時如果檢查到bash shell執行的話(對於/etc/profile還要先檢查是否互動式運行),也會執行這兩個檔案。

我們來看看這兩個bashrc做了什麼

對於/etc/bash.bashrc:首先檢查是否互動式運行,不是就什麼都不做。是的話,後面是一堆亂七八糟的操作。

對於~/.bashrc:首先檢查是否互動式運行,不是就什麼都不做。是的話,後面一堆亂七八糟的操作,其中有一些別名操作,我們平常用的ll就是在這裡設定了,是ls -alF的別名。

因為每次啟動shell進程這裡都會執行,所以一般也可以在這後面配置環境變數。

最常見的配置方法是vim ~/.bashrc然後在最後幾行加上環境變數的配置,然後source ~/.bashrc或者重啟終端即可。

# System-wide .bashrc file for interactive bash(1) shells.# To enable the settings / commands in this file for login shells as well,# this file has to be sourced in /etc/profile.# If not running interactively, don't do anything[ -z "$PS1" ] && return...
# ~/.bashrc: executed by bash(1) for non-login shells.# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)# for examples# If not running interactively, don't do anythingcase $- in    *i*) ;;      *) return;;esac...# some more ls aliasesalias ll='ls -alF'alias la='ls -A'alias l='ls -CF'

 

(5) 寫在後面

最後說一下,各個linux系統下的profile檔案和bashrc檔案都有所不同,我用的是ubuntu16.04,其它系統可能有所不同,可以自己看裡面的shell代碼進行理解和實踐驗證。

此次總結大致理順了一下整個環境變數的“流通過程”,理解這個過程之後思路應該清晰了很多,如有錯誤,歡迎指正。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.