本文以redhat 8.0操作系統平台為背景,闡述如何實現啟動級別為3時的自動登錄,及自動運行相應程序,並簡要介紹了如何在redhat 8.0下自動登錄X window(系統啟動級別為5),並自動運行指定的應用程序。
一、啟動級別為3時自動登錄的實現 啟動級別為3時自動登錄的實現涉及兩個軟件包:mingetty-1.00-3.src.rpm軟件包及util-Linux-2.11r-10.src.rpm軟件包。 (1)mingetty-1.00-3.src.rpm軟件包 對於啟動級別為3的自動登錄的實現,仍然需要考察/etc/inittab腳本, 3:123:respawn:/sbin/mingetty tty3 因此,如果想在啟動級別3的情況下實現自動登錄,必須要了解mingetty的功能,甚至要修改mingetty的代碼。用命令rpm -qf /sbin/mingetty 可知redhat 8.0版本的mingetty包含在mingetty-1.00-3.src.rpm軟件包中,下載該軟件包,安裝源代碼,缺省情況下,代碼會安裝在/usr/src/redhat/下,我們關心的只是mingetty.c源文件。mingetty.c約有五百行代碼,主要實現如下功能: 打開指定的tty(由參數指定); 提示用戶登錄(login:); 獲得登錄用戶名; 把用戶登錄名作為參數,調用/bin/login。 我們所關心的部分實質上只有以下三行: ... ... 438 while ((logname = get_logname ()) == 0); //mingetty.c文件438行 439 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL); 440 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]); ... ... 第一行的功能是輸出login提示,並獲得用戶輸入的登錄用戶名,登錄用戶名由logname返回。因此,可作如下修改 ... ... 438 // while ((logname = get_logname ()) == 0); //注釋掉本行,不再提示login: 439 logname = "root"; //添加本行代碼 440 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL); 441 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]); ... ... 注意,這裡假定用戶以超級用戶身份登錄。 第二行以用戶登錄名為參數,調用/bin/login程序,進一步實現登錄。因此,要想實現自動登錄,還應該了解/bin/login的功能,必要時還應修改其源代碼。 第三行為出錯處理。 (2)util-linux-2.11r-10.src.rpm軟件包 采用同樣的方法,查看/bin/login所屬軟件包(redhad8.0版本的login包含在util-linux-2.11r-10.src.rpm軟件包中),下載並安裝util-linux-2.11r-10.src.rpm,login可執行文件有幾個源文件編譯而成,我們最關心的是login.c源文件(大約1500行的代碼)。下面簡要分析一下login要實現的功能,並對相應部分作必要的修改。 Login程序主要可以分為以下幾個主要部分: 1.Login首先檢查登錄者是否為超級用戶,如果不是超級用戶,並且存在/etc/nologin文件,則輸出該文件內容,並中止登錄過程;主要由checknologin()實現; 2.如果登錄用戶是超級用戶,那麼login必須在/etc/securetty/中指定的tty列表中實現登錄,否則將導致登錄失敗。同樣可以不指定/etc/securetty文件,此時,超級用戶可以在任何tty上登錄。 3.經過前兩步測試後,login接下來將提示輸入登錄密碼(由getpass()調用完成,有興趣的讀者可參考其手冊頁面),並進行驗證,如果密碼不對,則提示重新登錄。 4.順利經過密碼驗證後,login還將檢查是否存在.hushlogin文件,如果該文件存在,則執行一次"quiet"登錄(所謂的quiet登錄指的是,登錄時不再提示郵件mail,不再顯示最後一次登錄時間,不輸出任何消息。啟動級別為3時,正常情況下輸出這些信息) 5.login接下來設置登錄tty的用戶ID和組ID,並設置相應的環境變量,包括HOME、PATH、SHELL、TERM、LOGNAME等。對於普通用戶來說,PATH缺省被設置成/usr/local/bin: /bin/usr/bin:;對於超級用戶來說,PATH被設置成/sbin: /bin: /usr/sbin: /usr/bin: 6.login的最後一步是為用戶啟動shell。如果在/etc/passwd中沒有為用戶指定shell,那麼將使用/bin/sh,如果在/etc/passwd中沒有給出當前工作目錄,則使用"/"。 至此,一個完整的登錄過程就結束了。 從以上對login源程序分析過程中可發現,如果要實現自動登錄,應該在第三步做文章,設法繞過提示輸入密碼以及對密碼進行驗證這一過程。實際上很簡單,login源程序對是否要求輸入密碼設置了一個開關控制passwd_req,缺省情況下,其值為1(passwd_req = 1),即要求輸入密碼進行身份驗證。把該行代碼改為(passwd_req = 0)後,問題就解決了。即對源文件作如下修改即可: ... ... 402 fflag = hflag = pflag = 0; //login.c文件402行 403 //passwd_req = 1 //缺省時,要求進行密碼驗證,注釋掉本行 404 passwd_req = 0 //添加本行 ... ... 修改後,可以直接使用util-linux-2.11r-10.src.rpm提供的Makefile進行重新編譯,也可以自己對其編譯: gcc -o login login.c setproctitle.c checktty.c xstrncpy.c -Wall -lcrypt注意包含後面的編譯選項-lcrypt,否則會出問題。 有了新版的mingetty及login後,拷貝mingetty到/sbin/目錄,拷貝login到/bin目錄,並將/etc/inittab中的啟動級別設置為3,再重新引導系統即可(讀者可以自己寫一個腳本實現上述過程)。 如果讀者對mingetty或login代碼的其他部分感興趣,可以反復修改login.c或mingetty.c的源代碼,測試一下代碼的功能,這裡要注意的是,在拷貝新版mingetty和login之前,一定要把原來的mingetty和login備份,同時還要准備系統引導盤(有系統安裝盤亦可,這樣讀者有機會鍵入linux rescue),在測試新版程序前更應如此,如果對代碼修改稍有不當,系統將不能正常啟動。 如果不想再作進一步的代碼測試,只是按本文給出的方法進行代碼修改,在系統啟動上不會出現什麼問題。
二、自動登錄後,自動運行特定的應用程序 在實現了啟動級別3時的自動登錄後,自動運行應用程序非常簡單,把應用程序添加在/etc/rc.d/rc.local腳本中既可。(讀者可以嘗試一下把startx加入腳本中,看一看效果如何。在某種意義上,又增加了一種自動登錄X window的方法)
三、對自動登錄X window(系統啟動級別為5),並自動運行指定的應用程序的補充 在"如何實現自動登錄linux"中,主要以redhat 7.2平台為背景進行闡述的,其中的自動登錄部分可以直接用於redhat 8.0中,不需要任何修改。 但是,登錄後自動運行應用程序的接口在redhat 8.0中有所不同,主要是登錄gnome後,自動運行應用程序的接口有所改變:首先點擊面板上的GNOME幫助(那個紅色的小帽子),然後選擇/其它/首選項/Sessions,在Session對話框的啟動程序屬性頁中添加要啟動的程序即可。 對於登錄kde後,自動運行程序的接口沒有改變。
四、結論 本文同"如何實現自動登錄linux"一文,基本上解決了如何實現自動登錄Linux,並自動運行相應應用程序的問題。對於兩個最常見的啟動級別(3、5),都給出了各自的方法。 在系統初始化到mingetty及login這一階段,內核實際上已經完成了引導過程,已經到了系統初始化的最高階段,與內核沒什麼關系了。此時,主要是/sbin/init根據/etc/inittab的內容而相機行事。讀者可通過(man 8 init)或者(man 5 inittab)了解更多東西。 在對文中提到的軟件包修改時,請遵守GNU General Public License(GPL)相關標准,另外,替換login通常被視為黑客行為,應當謹慎行事。 參考文獻 1.login手冊頁面 2.mingetty-1.00-3.src.rpm,在redhat 8.0的發行版本的源代碼中,包含該軟件包; 3.util-linux-2.11r-10.src.rpm,