S中設(shè)置的啟動設(shè)備(通常是硬盤)啟動,
創(chuàng)新互聯(lián)是一家網(wǎng)站制作、做網(wǎng)站,提供網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,網(wǎng)站制作,建網(wǎng)站,按需網(wǎng)站開發(fā),網(wǎng)站開發(fā)公司,自2013年創(chuàng)立以來是互聯(lián)行業(yè)建設(shè)者,服務(wù)者。以提升客戶品牌價值為核心業(yè)務(wù),全程參與項目的網(wǎng)站策劃設(shè)計制作,前端開發(fā),后臺程序制作以及后期項目運營并提出專業(yè)建議和思路。
接著啟動設(shè)備上安裝的引導(dǎo)程序lilo或grub開始引導(dǎo)Linux,Linux首先進(jìn)行內(nèi)核的引導(dǎo),
接下來執(zhí)行init程序,init程序調(diào)用了rc.sysinit和rc等程序,rc.sysinit和rc當(dāng)完成系
統(tǒng)初始化和運行服務(wù)的任務(wù)后,返回init;init啟動了mingetty后,打開了終端供用戶登
錄系統(tǒng),用戶登錄成功后進(jìn)入了Shell,這樣就完成了從開機(jī)到登錄的整個啟動過程。
加載內(nèi)核
LILO啟動之后,如果你選擇了Linux作為準(zhǔn)備引導(dǎo)的操作系統(tǒng),第一個被加載的東西就是內(nèi)核。請記住此時的計算機(jī)內(nèi)存中還不存在任何操作系統(tǒng), PC(因為它們天然的設(shè)計缺陷)也還沒有辦法存取機(jī)器上全部的內(nèi)存。因此,內(nèi)核就必須完整地加載到可用RAM的第一個兆字節(jié)之內(nèi)。為了實現(xiàn)這個目的,內(nèi)核是被壓縮了的。這個文件的頭部包含著必要的代碼,先設(shè)置CPU進(jìn)入安全模式(以此解除內(nèi)存限制),再對內(nèi)核的剩余部分進(jìn)行解壓縮。
執(zhí)行內(nèi)核
內(nèi)核在內(nèi)存中解壓縮之后,就可以開始運行了。此時的內(nèi)核只知道它本身內(nèi)建的各種功能,也就是說被編譯為模塊的內(nèi)核部分還不能使用。最基本的是,內(nèi)核必須有足夠的代碼設(shè)置自己的虛擬內(nèi)存子系統(tǒng)和根文件系統(tǒng)(通常就是ext2文件系統(tǒng))。一旦內(nèi)核啟動運行,對硬件的檢測就會決定需要對哪些設(shè)備驅(qū)動程序進(jìn)行初始化。從這里開始,內(nèi)核就能夠掛裝根文件系統(tǒng)(這個過程類似于Windows識別并存取C盤的過程)。內(nèi)核掛裝了根文件系統(tǒng)之后,將啟動并運行一個叫做 init的程序。
注意:在這里我們故意略去了Linux內(nèi)核啟動的許多細(xì)節(jié),這些細(xì)節(jié)只有內(nèi)核開發(fā)人員才感興趣。如果你好奇的話,可以訪問http://地址處的 “Kernel Hackers Guide”。
init進(jìn)程
init進(jìn)程是非內(nèi)核進(jìn)程中第一個被啟動運行的,因此它的進(jìn)程編號PID的值總是1。init讀它的配置文件/etc/inittab,決定需要啟動的運行級別(Runlevel)。從根本上說,運行級別規(guī)定了整個系統(tǒng)的行為,每個級別(分別由0到6的整數(shù)表示)滿足特定的目的。如果定義了 initdefault級別,這個值就直接被選中,否則需要由用戶輸入一個代表運行級別的數(shù)值。
輸入代表運行級別的數(shù)字之后,init根據(jù)/etc/inittab文件中的定義執(zhí)行一個命令腳本程序。缺省的運行級別取決于安裝階段對登錄程序的選擇:是使用基于文本的,還是使用基于X-Window的登錄程序。
rc命令腳本程序
我們已經(jīng)知道,當(dāng)運行級別發(fā)生改變時,將由/etc/inittab文件定義需要運行哪一個命令腳本程序。這些命令腳本程序負(fù)責(zé)啟動或者停止該運行級別特定的各種服務(wù)。由于需要管理的服務(wù)數(shù)量很多,因此需要使用rc命令腳本程序。其中,最主要的一個是/etc/rc.d/rc,它負(fù)責(zé)為每一個運行級別按照正確的順序調(diào)用相應(yīng)的命令腳本程序。我們可以想象,這樣一個命令腳本程序很容易變得難以控制!為了防止這類事件的發(fā)生,需要使用精心設(shè)計的方案。
對每一個運行級別來說,在/etc/rc.d子目錄中都有一個對應(yīng)的下級目錄。這些運行級別的下級子目錄的命名方法是rcX.d,其中的X就是代表運行級別的數(shù)字。比如說,運行級別3的全部命令腳本程序都保存在/etc/rc.d/rc3.d子目錄中。
在各個運行級別的子目錄中,都建立有到/etc/rc.d/init.d子目錄中命令腳本程序的符號鏈接,但是,這些符號鏈接并不使用命令腳本程序在 /etc/rc.d/init.d子目錄中原來的名字。如果命令腳本程序是用來啟動一個服務(wù)的,其符號鏈接的名字就以字母S打頭;如果命令腳本程序是用來關(guān)閉一個服務(wù)的,其符號鏈接的名字就以字母K打頭。
許多情況下,這些命令腳本程序的執(zhí)行順序都很重要。如果沒有先配置網(wǎng)絡(luò)接口,就沒有辦法使用DNS服務(wù)解析主機(jī)名!為了安排它們的執(zhí)行順序,在字母S 或者K的后面緊跟著一個兩位數(shù)字,數(shù)值小的在數(shù)值大的前面執(zhí)行。比如:/etc/rc.d/rc3.d/S50inet就會在 /etc/rc.d/rc3.d/S55named之前執(zhí)行(S50inet配置網(wǎng)絡(luò)設(shè)置,S55named啟動DNS服務(wù)器)。
存放在/etc/rc.d/init.d子目錄中的、被符號鏈接上的命令腳本程序是真正的實干家,是它們完成了啟動或者停止各種服務(wù)的操作過程。當(dāng) /etc/rc.d/rc運行通過每個特定的運行級別子目錄的時候,它會根據(jù)數(shù)字的順序依次調(diào)用各個命令腳本程序執(zhí)行。它先運行以字母K打頭的命令腳本程序,然后再運行以字母S打頭的命令腳本程序。對以字母K打頭的命令腳本程序來說,會傳遞Stop參數(shù);類似地對以字母S打頭的命令腳本程序來說,會傳遞 Start參數(shù)。
編寫自己的rc命令腳本
在維護(hù)Linux系統(tǒng)運轉(zhuǎn)的日子里,肯定會遇到需要系統(tǒng)管理員對開機(jī)或者關(guān)機(jī)命令腳本進(jìn)行修改的情況。有兩種方法可以用來實現(xiàn)修改的目的:
● 如果所做的修改只在引導(dǎo)開機(jī)的時候起作用,并且改動不大的話,可以考慮簡單地編輯一下/etc/rc.d/rc.local腳本。這個命令腳本程序是在引導(dǎo)過程的最后一步被執(zhí)行的。
● 如果所做的修改比較細(xì)致,或者還要求關(guān)閉進(jìn)程使之明確地停止運行,則需要在/etc/rc.d/init.d子目錄中添加一個命令腳本程序。這個命令腳本程序必須可以接受Start和Stop參數(shù)并完成相應(yīng)的操作。
第一種方法,編輯/etc/rc.d/rc.local腳本,當(dāng)然是兩種方法中比較簡單的。如果想在這個命令腳本程序中添加內(nèi)容,只需要使用喜歡的編輯器程序打開它,再把打算執(zhí)行的命令附加到文件的末尾就可以了。這對一兩行的修改來說的確很便利。
如果確實需要使用一個命令腳本程序,這時必須選擇第二個方法。編寫一個rc命令腳本程序的過程并不像想象中那么困難。我們下面就給出一個例子,看看它是怎樣實現(xiàn)的(順便說一句,你可以把我們的例子當(dāng)作范本,按照自己的需要進(jìn)行修改和添加)。
假設(shè)你打算每隔60分鐘調(diào)用一個特殊的程序來彈出一條消息,提醒自己需要從鍵盤前面離開休息一會兒,命令腳本程序?qū)ㄏ旅鎺讉€部分:
● 關(guān)于這個命令腳本程序功能的說明(這樣就不會在一年之后忘記它);
● 在試圖運行它之前驗證這個命令腳本程序確實存在;
● 接受start和stop參數(shù)并執(zhí)行要求的動作。
參數(shù)給定后,我們就可以編寫命令的腳本程序。這個程序很簡單,大家可以自己編寫一下,我在這里就不給出了。
編寫好新的命令腳本程序之后,再從相關(guān)的運行級別子目錄中加上必要的符號鏈接,來控制這個命令腳本程序的啟動或者停止。在我的印象中,只想讓它在運行級別3或者運行級別5中啟動,原因是我認(rèn)為只有這兩個運行級別才是日常工作的地方。最后,希望這個命令腳本程序在進(jìn)入運行級別6(重啟動)的時候被關(guān)閉。
激活或者禁止服務(wù)項目
有的時候會發(fā)現(xiàn),在引導(dǎo)的時候并不需要某個特定的服務(wù)被啟動。如果你正在考慮使用Linux替換Windows NT的文件和打印服務(wù)器,就更是如此。
我們已經(jīng)知道,在特定的運行級別子目錄中給符號鏈接改個名稱,就可以讓該服務(wù)不被啟動,如把其名稱的第一個字母由S改為K。一旦熟練掌握了命令行和符號鏈接,就會發(fā)現(xiàn)這是激活或者禁止服務(wù)的最快辦法。
在學(xué)習(xí)這個改名方法的時候,可能會覺得圖形化的操作界面ksysv比較容易掌握。雖然它原來是設(shè)計使用在KDE環(huán)境里的,但在 Red Hat Linux 7.2下缺省安裝的GNOME環(huán)境里也運行得很好。如果想啟動它,只需簡單地打開一個xterm窗口,并輸入ksysv命令就可以了。屏幕上會出現(xiàn)一個窗口,其中列出了能夠修改的全部參數(shù),需要時還包括在線幫助。
警告:如果是在一個現(xiàn)實中的系統(tǒng)上學(xué)習(xí)本文的知識,要多多運用常識。當(dāng)試著對啟動腳本程序進(jìn)行修改的時候,要記住所做的修改可能會造成你的系統(tǒng)不能正常工作,而且無法采用重啟動的方法恢復(fù)。不要在正常運轉(zhuǎn)的系統(tǒng)上實驗新的設(shè)置,對你準(zhǔn)備修改的文件要全部進(jìn)行備份。最重要的是,在手邊要準(zhǔn)備一張引導(dǎo)盤以防不測
另外,虛機(jī)團(tuán)上產(chǎn)品團(tuán)購,超級便宜
public static void pdfToSWF(String pdfPath,String swfPath) {
String cmd = "cmd /c pdf2swf.exe -t "+pdfPath+" -o "+swfPath+" -s flashversion=9";
String dir = ReadPropertis.getSWFToolsPath();
try {
java.lang.Runtime.getRuntime().exec(cmd,null,new File(dir));
} catch (IOException e) {
logger.error("創(chuàng)建SWF文件異常",e);
}
}
system函數(shù)
例如想調(diào)用ls命令,那么可以使用system("ls"),這樣在程序運行到這里的時候屏幕就打印ls列出的東西了.具體可以用man查看system函數(shù)的用法
system函數(shù)的用法肯定是沒問題的.
jpeglib庫我沒用過,不是很清楚.不過你可以試試直接在shell下執(zhí)行djpeg -bmp 256 image.jpeg22.bmp,看看是不是能成功生成.
在java程序中如何調(diào)用linux的命令?如何調(diào)用shell腳本呢?
這里不得不提到j(luò)ava的process類了。
process這個類是一個抽象類,封裝了一個進(jìn)程(你在調(diào)用linux的命令或者shell腳本就是為了執(zhí)行一個在linux下執(zhí)行的程序,所以應(yīng)該使用process類)。
process類提供了執(zhí)行從進(jìn)程輸入,執(zhí)行輸出到進(jìn)程,等待進(jìn)程完成,檢查進(jìn)程的推出狀態(tài),以及shut down掉進(jìn)程。
至于詳細(xì)的process類的介紹放在以后介紹。
另外還要注意一個類:Runtime類,Runtime類是一個與JVM運行時環(huán)境有關(guān)的類,這個類是Singleton的。
這里用到的Runtime.getRuntime()方法是取得當(dāng)前JVM的運行環(huán)境,也是java中唯一可以得到運行環(huán)境的方法。(另外,Runtime的大部分方法都是實例方法,也就是說每次運行調(diào)用的時候都需要調(diào)用到getRuntime方法)
下面說說Runtime的exec()方法,這里要注意的有一點,就是public Process exec(String [] cmdArray, String [] envp);這個方法中cmdArray是一個執(zhí)行的命令和參數(shù)的字符串?dāng)?shù)組,數(shù)組的第一個元素是要執(zhí)行的命令往后依次都是命令的參數(shù),envp感覺應(yīng)該和C中的execve中的環(huán)境變量是一樣的,envp中使用的是name=value的方式。
下面說一下,如何使用process來調(diào)用shell腳本
例如,我需要在linux下實行l(wèi)inux命令:sh test.sh,下面就是執(zhí)行test.sh命令的方法:
這個var參數(shù)就是日期這個201102包的名字。
String shpath="/test/test.sh"; //程序路徑
Process process =null;
String command1 = “chmod 777 ” + shpath;
process = Runtime.getRuntime().exec(command1);
process.waitFor();
String var="201102"; //參數(shù)
String command2 = “/bin/sh ” + shpath + ” ” + var;
Runtime.getRuntime().exec(command2).waitFor();
注意:
1
我為什么要使用 chmod 777命令呢?在有的機(jī)器上面,可能沒有設(shè)置權(quán)限問題。這是你在linux下面執(zhí)行shell腳本需要注意的問題。沒有的話,就需要添加權(quán)限,就用chmod 777,否則在執(zhí)行到Runtime.getRuntime().exec的時侯會出現(xiàn)Permission denied錯誤。
2
waitFor()這個也是必不可缺的,如果你需要執(zhí)行多行命令的話,把waitFor()這個加上。
Linux中啟動另一個可執(zhí)行文件或程序用system函數(shù)最理想了,這個函數(shù)將在你編寫的那個程序的內(nèi)部啟動另一個程序,從而創(chuàng)建一個新進(jìn)程,并等待這個進(jìn)程執(zhí)行完畢退出。如果正常執(zhí)行,system函數(shù)將返回被執(zhí)行程序的退出碼;如果無法運行這個程序,將返回錯誤代碼127;如果是其他錯誤,返回-1。這個函數(shù)的原型是:
#include stdlib.h
int system(const char *string);
參數(shù)string是將要執(zhí)行的程序的命令字符串。
還有一種執(zhí)行外部程序的方法是exec系列函數(shù),但這個系列的函數(shù)都是將當(dāng)前進(jìn)程的替換成新進(jìn)程,也就是說原來的進(jìn)程不存在了。
參數(shù)type可使用“r”代表讀取,“w”代表寫入。依照此type值,popen()會建立管道連到子進(jìn)程的標(biāo)準(zhǔn)輸出設(shè)備或標(biāo)準(zhǔn)輸入設(shè)備,然后返回一個文件指針。隨后進(jìn)程便可利用此文件指針來讀取子進(jìn)程的輸出設(shè)備或是寫入到子進(jìn)程的標(biāo)準(zhǔn)輸入設(shè)備中。此外,所有使用文件指針(FILE*)操作的函數(shù)也都可以使用,除了fclose()以外。 返回值:若成功則返回文件指針,否則返回NULL,錯誤原因存于errno中。 注意:在編寫具SUID/SGID權(quán)限的程序時請盡量避免使用popen(),popen()會繼承環(huán)境變量,通過環(huán)境變量可能會造成系統(tǒng)安全的問題。 例:C程序popentest.c內(nèi)容如下: #includestdio.h main() { FILE * fp; charbuffer[80]; fp=popen(“~/myprogram/test.sh”,”r”); fgets(buffer,sizeof(buffer),fp); printf(“%s”,buffer); pclose(fp); } 執(zhí)行結(jié)果如下: xiakeyou@ubuntu:~/myprogram$ vim popentest.c xiakeyou@ubuntu:~/myprogram$ gcc popentest.c -o popentest xiakeyou@ubuntu:~/myprogram$ ./popentest /home/d/e/xiakeyou xiakeyou@ubuntu:~/myprogram$ 只是偶能力可能有點有限,沒有太看懂。直接用system()倒是腳本可是執(zhí)行,只是返回值卻是一塌糊涂,試了多次也沒有找到什么規(guī)律。不免又看了一下上面的那篇博文,得到一些啟發(fā),可以這樣來實現(xiàn): 先將腳本的返回值利用 echo XXXXX 輸出到一個本地文件中 當(dāng)需要這個返回值是,可是通過C語言的文件操作函數(shù)來直接從文件中讀取 后來一想,這應(yīng)該就是上文中POPEN的實現(xiàn)方法! C程序調(diào)用shell腳本共有三種法子 :system()、popen()、exec系列函數(shù) system() 不用你自己去產(chǎn)生進(jìn)程,它已經(jīng)封裝了,直接加入自己的命令exec 需要你自己 fork 進(jìn)程,然后exec 自己的命令 popen() 也可以實現(xiàn)執(zhí)行你的命令,比system 開銷小 1)system(shell命令或shell腳本路徑); system()會調(diào)用fork()產(chǎn)生 子歷程,由子歷程來調(diào)用/bin/sh-c string來履行 參數(shù)string字符串所代表的命令,此命令履行 完后隨即返回原調(diào)用的歷程。在調(diào)用system()期間SIGCHLD 信號會被暫時擱置,SIGINT和SIGQUIT 信號則會被漠視 。 返回值:如果system()在調(diào)用/bin/sh時失敗則返回127,其他失敗原因返回-1。若參數(shù)string為空指針(NULL),則返回非零值。 如果 system()調(diào)用成功 則最后會返回履行 shell命令后的返回值,但是此返回值也有可能為system()調(diào)用/bin/sh失敗所返回的127,因 此最好能再反省 errno 來確認(rèn)履行 成功 。 system命令以其簡略 高效的作用得到很很廣泛 的利用 ,下面是一個例子 例:在~/test/目錄下有shell腳本test.sh,內(nèi)容為 #!bin/bash #test.sh echo hello 在同層目錄下新建一個c文件system_test.c,內(nèi)容為: #includestdlib.h int main() { system("~/test/test.sh"); } 履行 效果 如下: [root@localhost test]$gcc system_test.c -o system_test [root@localhost test]$./system_test hello [root@localhost test]$ 2)popen(char *command,char *type) popen()會調(diào)用fork()產(chǎn)生 子歷程,然后從子歷程中調(diào)用/bin/sh -c來履行 參數(shù)command的指令。參數(shù)type可應(yīng)用 “r”代表讀取,“w”代表寫入。遵循此type值,popen()會建立 管道連到子歷程的標(biāo)準(zhǔn) 輸出設(shè)備 或標(biāo)準(zhǔn) 輸入設(shè)備 ,然后返回一個文件指針。隨后歷程便可利用 此文件指針來讀取子歷程的輸出設(shè)備 或是寫入到子歷程的標(biāo)準(zhǔn) 輸入設(shè)備 中。此外,所有應(yīng)用 文 件指針(FILE*)操作的函數(shù)也都可以應(yīng)用 ,除了fclose()以外。 返回值:若成功 則返回文件指針,否則返回NULL,差錯 原因存于errno中。
本文標(biāo)題:linux程序用調(diào)用命令 linux調(diào)用命令行
地址分享:http://www.rwnh.cn/article24/dooceje.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號、關(guān)鍵詞優(yōu)化、網(wǎng)站策劃、全網(wǎng)營銷推廣、動態(tài)網(wǎng)站、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)