linux自動啟動shell和init概述(fedora use systemmd now!!!)

來源:互聯網
上載者:User

標籤:

  1. linux運行層級 
    linux啟動之後會在一個層級運行,下面列出了這些運行層級:
    0 系統停止
    1 單使用者系統,不需要登陸
    2 多使用者系統但不支援NFS,命令列模式登陸
    3 完整多使用者模式,命令列模式登陸
    4 未用
    5 X11圖形模式,圖形模式登陸
    6 重新啟動系統
    這些可以在/etc/initab檔案中可以看到0-6級的注釋,程式碼片段如下:
    # Default runlevel. The runlevels used by RHS are:
    #   0 - halt (Do NOT set initdefault to this)
    #   1 - Single user mode
    #   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
    #   3 - Full multiuser mode
    #   4 - unused
    #   5 - X11
    #   6 - reboot (Do NOT set initdefault to this)
    1.層級 0
      系統停止。注意不要把該層級設定為預設模式,否則系統每次啟動以後就會自動停止,無法進入。
    這個運行層級主要用於關閉任務,在 rc0.d 目錄下的各個串連命令都是此層級的命令。在關閉時,這些命令逐個執行。它們將殺掉所有進程、關閉虛擬記憶體和分頁檔、卸載檔案系統和交換分區。
    關機操作在 DOS 下和 Linux 下截然不同。在 DOS 提示符下,可以很放心地直接關閉電源。但是,在 Linux 下不能這麼做。Linux 的檔案系統在啟動時被裝入,在關閉時要被卸載。這種差別正是 Linux 強大功能的前提。
    在 Linux 下,要通過輸入命令 shutdown 加上參數來關閉、重啟電腦或者通過按下熱鍵“Ctrl”+“Alt”+“Del”來重新啟動。
    2.層級 1
    單一使用者模式。該模式只能許可一個使用者從本機電腦上登入 rc1.d 目錄下的所有檔案與此運行層級相連。此運行層級一般用於系統管理與維護,如:給 Linux 系統升級,安裝新軟體等等。
    在此模式下,只能由管理員進入而其他使用者無法登入。因為在啟動時,檔案系統被載入但是網路卻沒有被載入,無法通過網路登入。
    3.層級 2
    多使用者模式。使用者可以通過網路進行登入。在不支援網路的情況下該模式和模式 3 是相的,rc2.d 目錄下所有檔案與此層級相連。
    4.層級 3
    完全多使用者模式。這是預設的運行模式,在此模式下所有網路服務程式一起運行。rc3.d錄下的檔案與此層級相連。
    5.層級 4
    未使用模式,rc4.d 目錄與此層級相連。這一層級是使用者自訂的運行層級,使用者可以根需要自己定義。如果想運行此層級的話,必須在 rc3.d 目錄下放入串連檔案,就像其他 rc*.d目錄下的檔案,並指明是啟動還是終止進程。
    6.層級 5
    在 Linux 下運行 X  Window 就是使用這一層級。在此層級下除了網際網路的網域名稱伺服器的named 與層級 3 不同,其餘的都相同。
    7.層級 6
    這是個重新啟動系統的運行層級。rc6.d 目錄與此層級相連。既然是重新啟動也就是關閉當前系統,但不關閉電源,所以此目錄下的串連與層級為 0 的在rc0.d 下的串連基本相同。不同之處在於,雖然它們都執行 halt(關閉)命令,但是給 halt 傳遞的參數不一樣,因而層級 6能夠重新啟動系統。
  2. inittab檔案解釋
    inittab檔案的格式:
    label:runlevel:action:process
    label:
    1~4字元的標籤,可以是任一字元構成的字串,表示輸入的值。一些系統label為2個字元。某些特定的標籤是常用的,在Red Hat Linux中使用的標籤是:
    id 用來定義預設的init啟動並執行層級
    si 是系統初始化的進程
    ln 其中的n從1~6,指明該進程可以使用的runlevel的層級
    ud 是升級進程
    ca 指明當按下Ctrl+Alt+Del是啟動並執行進程
    pf 指當UPS表明斷電時啟動並執行進程
    pr 是在系統真正關閉之前,UPS發出電源恢複的訊號時需要啟動並執行進程
    x 是將系統轉入X終端時需要啟動並執行進程
    runlevel:
    定義該記錄項被調用時的運行層級,可以由一個或多個運行層級構成,也可以是空,空則代表運行層級0~6.
    當請求init改變運行層級時,那些rstate欄位中不包括新運行層級的進程將收到SIGTERM警告訊號,並且最後被殺死;只有a、b、c啟動的命令外(a、b、c不是真正的運行層級) ????

    action:
    定義了該進程應該運行在何種狀態下,即如何處理process欄位指定的進程.
    代碼:
    boot 只有在系統啟動時,init才處理這樣的記錄項,啟動相應進程,忽略runlevel,並不等待處理結束就去處理下一個記錄項。當這樣的進程終止時,系統也不重啟它。
    bootwait 系統啟動後,當第一次從單一使用者模式進入多使用者模式時處理這樣的記錄項,init啟動這樣的進程,並且等待它的處理結束,然後再進行下一個記錄項的處理,當這樣的進程終止時,系統也不重啟它。
    ctrlaltdel 當Ctrl+Alt+Del三個鍵同步選取時運行,把SIGINT訊號發送給init。忽略 runlevel
    initdefault 指定一個預設的運行層級,只有當init一開始被調用時才掃描這一項,如果runlevel
    欄位指定了多個運行層級,其中最大的數字是預設的運行層級,如果runlevel
    欄位是空的,init認為欄位是0123456,於是進入層級6,這樣便陷入了一個迴圈,如果inittab檔案中沒有包含initdefault的記錄項,則在系統啟動時請求使用者為它指定一個初始運行層級
    kbrequest 當init從鍵盤中收到訊號時運行。這裡要求鍵盤組合符合KeyBoardSigral(參見/usr/share/doc/kbd-*關於鍵盤組合的文檔)
    off  啟動process欄位指定的進程如果指定的進程正在運行,init就給它發SIGTERM警告訊號,在向它發出訊號SIGKILL強制其結束之前等待5秒,如果這樣的進程不存在,則忽略這一項。
    once不等待處理結束就去處理下一記錄項。當這樣的進程終止時,也不再重新啟動它,在進入新的運行層級時,如果這樣的進程仍在運行,init也不重新啟動它。
    ondemand 功能同respawn 當系統指定特定的運行層級A、B、C時運行
    powerfail 當init收到SIGPWR(斷電)訊號時運行
    powerokwait 當收到SIGPWD訊號且/etc/檔案中的電源狀態包含OK時運行
    powerwait 當收到SIGPWD訊號,並且init等待進程結束時運行
    respawn 不管何時process中止,init都重新啟動進程,並且init不等到啟動結束而繼續掃描inittab中的後續process。如果process已經存在,就什麼也不做。
    sysinit 在運行boot或bootwait進程之前運行,指定的進程在存取控制台之前執行,這樣的記錄項僅用於對某些裝置的初始化,目的是為了使init在這樣的裝置上向使用者提問有關運行層級的問題,init需要等待進程運行結束後才繼續。
    wait 啟動process欄位指定的進程,並等到處理結束才去處理inittab中的下一記錄項。

    process欄位包含init執行的進程,該進程採用的格式與在命令列下運行該進程的格式一樣,因此process欄位都以該進程的名字開頭,緊跟著是運行時,緊跟著是運行時要傳遞給該進程的參數。比如/sbin/shutdown -t3 -rnow,該進程在按下Ctrl+Alt+Del時執行,在命令列下也可以直接輸入來重新啟動系統。
    Process欄位中進程可以是任意的守候進程、可執行指令碼或程式。
    另外:在任何時候,可以在檔案inittab中添加新的記錄項,層級Q/q不改變當前的運行層級,重新檢查inittab檔案,可以通過命令init Q或init q使init進程立即重新讀取並處理檔案inittab.

    特殊目的的記錄
    仔細學習例子檔案,學習應用其中關於inittab的文法格式。該檔案的大多數內容都可以忽略,因為超過一半的內容都是注釋,剩餘的一些檔案內容主要是用來實現某些特殊的功能:
    id 的值表明預設的runlevel是3。
    ud 的值可以喚醒/sbin/update進程,該進程為保持磁碟的完整性,將在對磁碟進行I/O操作之前清空整個I/O緩衝區。
    pf、pr和ca的值只被特定的中斷所調用。
    如果系統是專用的X終端,則只需x的輸入值。
    getty進程來提供虛擬終端裝置的服務,例如:
    3:2345:respawn:/sbin/mingetty tty3
    標籤欄位的值是3,3是裝置tty3的數字尾碼,tty3與相應的進程相關聯,該getty進程可以啟動的runlevel是2、3、4和5,當該進程終止時,init馬上就重新啟動它。啟動進程的路徑名是/sbin/mingetty,該進程是實現虛擬終端支援的最小版本的getty,為tty3提供啟動虛擬設備的進程。
    si::sysinit:/etc/rc.d/rc.sysinit
    該值告訴init程式運行/etc/rc.d/rc.sysinit指令檔來初始化系統,該指令檔與所有啟動的指令碼類似,它只是一個包含Linux的shell命令的可執行檔,注意輸入的字串必須包括該指令碼的完整路徑。不同版本的Linux存放該指令碼的位置也不相同,但不用刻意去記憶這些位置,只需查看/etc/inittab檔案即可,該檔案中包含啟動指令檔的確切位置。

    redhat 9 預設initab檔案內容:
    default runlevel
    0 - halt (do not set initdefault to this)
    1 - single user mode
    2 - multiuser, without NFS (the same as 3, if you do not have a neworking)
    3 - full multiuser mode
    4 - unused
    5 - X11
    6 - reboot halt (do not set initdefault to this)
    id:5:initdefault:
    //預設init進程被調用時的運行層級為5(不能設為0和6,這樣系統將不能啟動)
    si::sysinit:/etc/rc.d/rc.sysinit
    //si是系統初始化進程,init程式運行/etc/rc.d/rc.sysinit指令檔來初始化系統,init等待指令碼運行結束才繼續運行下個進程。
    l0:0:wait:/etc/rc.d/rc 0
    l1:1:wait:/etc/rc.d/rc 1
    l2:2:wait:/etc/rc.d/rc 2
    l3:3:wait:/etc/rc.d/rc 3
    l4:4:wait:/etc/rc.d/rc 4
    l5:5:wait:/etc/rc.d/rc 5
    l6:6:wait:/etc/rc.d/rc 6
    //對相應運行層級,運行指令碼/etc/rc.d/rc,並傳入相應運行級參數0~6
    ca::ctrlaltdel:/sbin/shutdown -t3 -r now
    //按下ctrl+alt+del時執行shutdown -t3 -r now
    pf::powerfail:/sbin/shutdown -f -h +2
    //當UPS電源提示斷電的時候,他還將提供幾分鐘時間供電,這時系統執行shutdown -f -h +2 (-f 表示重啟的時候跳過檔案系統的檢查)

    pr:12345:powerwait:/shutdown -c
    //表示供電恢複時取消正在執行的shutdown命令。
    1:2345:respawn:/sbin/mingetty tty1
    2:2345:respawn:/sbin/mingetty tty2
    3:2345:respawn:/sbin/mingetty tty3
    4:2345:respawn:/sbin/mingetty tty4
    5:2345:respawn:/sbin/mingetty tty5
    6:2345:respawn:/sbin/mingetty tty6
    //2345運行級,運行對應的終端程式
    x:5:respawn:/etc/X11/prefdm -nodaemon
    //如果是x終端模式要啟動並執行程式
  3. linux自動啟動指令碼
    linux啟動之後會運行一個init程式,首先讀取inittab設定檔,決定系統的運行模式,在讀取inittab的過程中,執行rc0.d~rc6.d目錄下的運行層級指令碼,然後執行/etc/rc.local;
    由於執行rc0.d~rc6.d目錄下的運行層級指令碼是執行/etc/rc.d/rc指令碼執行的那麼我們就來看看這個指令碼
    /etc/rc.d/rc指令碼說明:
    #! /bin/bash
    #
    # rc            This file is responsible for starting/stopping
    #               services when the runlevel changes.
    #
    # Original Author:      
    #               Miquel van Smoorenburg, <[email protected]>
    #
    # check a file to be a correct runlevel script
    check_runlevel ()
    {
     # Check if the file exists at all.
     #判斷檔案存在,並可執行
     [ -x "$1" ] || return 1
     
     # Reject backup files and files generated by rpm.
     #拒絕備份檔案格式的檔案名稱
     case "$1" in
      *.rpmsave|*.rpmorig|*.rpmnew|*~|*.orig)
       return 1
       ;;
     esac
     return 0
    }
    # Now find out what the current and what the previous runlevel are.
    # 擷取到運行層級,如inittab中的/etc/rc.d/rc 0~6指定了運行層級,這兒的參數$1就是inittab中的命令傳的的參數0~6的數字
    argv1="$1"
    set `/sbin/runlevel`
    runlevel=$2
    previous=$1
    export runlevel previous
    #設定變數,當前運行層級,上一個運行層級
    #如果沒有上一個運行層級,那麼previous=N
    #載入/etc/init.d/functions指令碼,載入需要用到的函數定義
    . /etc/init.d/functions
    # See if we want to be in user confirmation mode
    if [ "$previous" = "N" ]; then
     if [ -f /var/run/confirm ] \
       || grep -i confirm /proc/cmdline >/dev/null ; then
      rm -f /var/run/confirm
      CONFIRM=yes
      export CONFIRM
      echo $"Entering interactive startup"
     else
      echo $"Entering non-interactive startup"
     fi
    fi
    # Get first argument. Set new runlevel to this argument.
    # 如果$argv1不是空串,賦予runlevel為argv1指定的運行級
    [ -n "$argv1" ] && runlevel="$argv1"
    # Is there an rc directory for this new runlevel?
    # 如果沒有對應層級的rc($runlevel).d的目錄,那麼程式退出
    [ -d /etc/rc$runlevel.d ] || exit 0

    # First, run the KILL scripts.
    #在相應運行層級的rc($runlevel).d目錄下,遍曆以K開頭的檔案,逐個取出
    #經過一系列判斷之後,執行指令碼,傳入stop參數
    for i in /etc/rc$runlevel.d/K* ; do
     check_runlevel "$i" || continue
     #判斷檔案存在可
     # Check if the subsystem is already up.
     subsys=${i#/etc/rc$runlevel.d/K??}
     [ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] \
      || continue
     # Bring the subsystem down.
    # 尋找在檔案中是否包含killproc和action單詞,-q選擇是不顯示輸入,只返回狀態
     # 執行指令碼,傳入stop參數
     if egrep -q "(killproc |action )" $i ; then
      $i stop
     else
      action $"Stopping $subsys: " $i stop
     fi
    done
    # Now run the START scripts.
    #擷取/etc/rc($runlevel).d目錄下,以S開頭得檔案
    #對每個檔案經過check之後,執行指令碼,傳入start參數
    for i in /etc/rc$runlevel.d/S* ; do
     check_runlevel "$i" || continue
     # Check if the subsystem is already up.
     subsys=${i#/etc/rc$runlevel.d/S??}
     [ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] \
      && continue
         
     # If we‘re in confirmation mode, get user confirmation
     if [ -n "$CONFIRM" ]; then
      confirm $subsys
      case $? in
       0) :;;
       2) CONFIRM=;;
       *) continue;;
      esac
     fi
     # Bring the subsystem up.
     if [ "$subsys" = "halt" -o "$subsys" = "reboot" ]; then
      export LC_ALL=C
      exec $i start
     fi
     if egrep -q "(daemon |action |success |failure )" $i 2>/dev/null \
       || [ "$subsys" = "single" -o "$subsys" = "local" ]; then
      $i start
     else
      action $"Starting $subsys: " $i start
     fi
    done
    分析上面得rc指令碼,就不難理解,為什麼啟動指令碼在rc0~6.d目錄下要用S開頭命名,停止指令碼要在rc0~6.d目錄下要用K開頭命名.

    我寫了一篇oracle自動啟動的文章,啟動的指令碼都是以S開頭,關閉的指令碼都是以K開頭,所以如果在編寫自動啟動程式,或者自動關閉程式的指令碼的時候,需要符合這個命名要求,才能被正確地執行.
  4. 使用者登入啟動
    使用者登入之後會運行/etc/profile,在執行profile的時候,最後有一段代碼,如下:
    for i in /etc/profile.d/*.sh ; do
        if [ -r "$i" ]; then
            . $i
        fi
    done
    這段代碼將遍曆/etc/profile.d目錄,執行所有以*.sh(以sh結尾)檔案名稱的指令碼;
    執行/etc/profile之後,然後執行使用者$HOME/.bash_profile指令碼
    如果/etc/profile.d在目錄下建立以*.sh檔案名稱的指令碼,在每次使用者登入的時候都會啟動;而有些用程式只需啟動一次,不需要每次登入都啟動,如資料庫,web服務,應用伺服器等.

    使用者可以根據自己的情況,決定登入時啟動程式,還是主機啟動是啟動程式.

    由於程式啟動並執行方式可能會不斷變化,有些使用者會把程式不斷地從一個目錄拷貝到另外一個目錄,名字也會不斷地修改,其實使用者只需要在一個地方存放應用程式,在配置目錄用ln -s建立一個阮串連就可以了;
  5. 退出時自動啟動
    退出登入時候,將自動執行$HOME/.bash_logout檔案,如果在該命令中添加一些程式執行命令,在使用者退出登入時這些命令將被自動啟動.如,在該檔案最後添加:agentctl stop,表示退出的時候將執行該命令,停止apache服務.
  6. 一些shell開機檔案
    $HOME/.bash_history 記錄使用者操作命令的記錄
    $HOME/.bash_logout 使用者退出登入的時候執行這個指令碼
    $HOME/.bash_profile 使用者登入,執行完/etc/profile之後執行.bash_profile(在unix下為.profile,linux下為unix)
    $HOME/.bashrc shell 登入時自動執行
    /etc/profile 每個使用者登入的時候都必須執行的指令碼
    /etc/fstab   系統每次啟動的時候需要mount磁碟的操作資訊

linux自動啟動shell和init概述(fedora use systemmd now!!!)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.