Ⅰ 用java實現一個模擬操作系統內核運行的程序。(1)進程式控制制:其中包括進程創建與撤銷
在編寫Java程序時,有時候需要在Java程序中執行另外一個程序。
1、啟動程序Java提供了兩種方法用來啟動其它程序:
(1)使用Runtime的exec()方法
(2)使用ProcessBuilder的start()方法
不管在哪種操作系統下,程序具有基本類似的一些屬性。一個程序啟動後就程序操作系統的一個進程,進程在執行的時候有自己的環境變數、有自己的工作目錄。Runtime和ProcessBuilder提供了不同的方式來啟動程序,設置啟動參數、環境變數和工作目錄。
能夠在Java中執行的外部程序,必須是一個實際存在的可執行文件,對於shell下的內嵌命令是不能直接執行的。
採用Runtime的exec執行程序時,首先要使用Runtime的靜態方法得到一個Runtime,然後調用Runtime的exec方
法。可以將要執行的外部程序和啟動參數、環境變數、工作目錄作為參數傳遞給exec方法,該方法執行後返回一個Process代表所執行的程序。
Runtime有六個exec方法,其中兩個的定義為:
public Process exec(String[] cmdarray, String[] envp, File dir)
public Process exec(String command, String[] envp, File dir)
cmdarray和command為要執行的命令,可以將命令和參數作為一個字元串command傳遞給exec()方法,也可以將命令和參數一個一個的方在數組cmdarray里傳遞給exec()方法。
envp為環境變數,以name=value的形式放在數組中。dir為工作目錄。
可以不要dir參數,或者不要envp和dir參數,這樣就多出了其它4個exec()方法。如果沒有dir參數或者為null,那麼新啟動的
進程就繼承當前java進程的工作目錄。如果沒有envp參數或者為null,那麼新啟動的進程就繼承當前java進程的環境變數。
也可以使用ProcessBuilder類啟動一個新的程序,該類是後來添加到JDK中的,而且被推薦使用。通過構造函數設置要執行的命令以及
參數,或者也可以通過command()方法獲取命令信息後在進行設置。通過directory(File directory)
方法設置工作目錄,通過environment()獲取環境變數信息來修改環境變數。
在使用ProcessBuilder構造函數創建一個新實例,設置環境變數、工作目錄後,可以通過start()方法來啟動新程序,與Runtime的exec()方法一樣,該方法返回一個Process對象代表啟動的程序。
ProcessBuilder與Runtime.exec()方法的不同在於ProcessBuilder提供了
redirectErrorStream(boolean redirectErrorStream)
方法,該方法用來將進程的錯誤輸出重定向到標准輸出里。即可以將錯誤輸出都將與標准輸出合並。
2、Process
不管通過那種方法啟動進程後,都會返回一個Process類的實例代表啟動的進程,該實例可用來控制進程並獲得相關信息。Process 類提供了執行從進程輸入、執行輸出到進程、等待進程完成、檢查進程的退出狀態以及銷毀(殺掉)進程的方法:
(1) void destroy()
殺掉子進程。
一般情況下,該方法並不能殺掉已經啟動的進程,不用為好。
(2) int exitValue()
返回子進程的出口值。
只有啟動的進程執行完成、或者由於異常退出後,exitValue()方法才會有正常的返回值,否則拋出異常。
(3)InputStream getErrorStream()
獲取子進程的錯誤流。
如果錯誤輸出被重定向,則不能從該流中讀取錯誤輸出。
(4)InputStream getInputStream()
獲取子進程的輸入流。
可以從該流中讀取進程的標准輸出。
(5)OutputStream getOutputStream()
獲取子進程的輸出流。
寫入到該流中的數據作為進程的標准輸入。
(6) int waitFor()
導致當前線程等待,如有必要,一直要等到由該 Process 對象表示的進程已經終止。
通過該類提供的方法,可以實現與啟動的進程之間通信,達到交互的目的。
3、從標准輸出和錯誤輸出流讀取信息
從啟動其他程序的Java進程看,已啟動的其他程序輸出就是一個普通的輸入流,可以通過getInputStream()和getErrorStream來獲取。
對於一般輸出文本的進程來說,可以將InputStream封裝成BufferedReader,然後就可以一行一行的對進程的標准輸出進行處理。
4、舉例
(1)Runtime.exec()import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
public class Test1 {
public static void main(String[] args) {
try {
Process p = null;
String line = null;
BufferedReader stdout = null;
//list the files and directorys under C:\
p = Runtime.getRuntime().exec("CMD.exe /C dir", null, new File("C:\\"));
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
//echo the value of NAME
p = Runtime.getRuntime().exec("CMD.exe /C echo %NAME%", new String[] {"NAME=TEST"});
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
(2)ProcessBuilderimport java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Test2 {
public static void main(String[] args) {
try {
List list = new ArrayList();
ProcessBuilder pb = null;
Process p = null;
String line = null;
BufferedReader stdout = null;
//list the files and directorys under C:\
list.add("CMD.EXE");
list.add("/C");
list.add("dir");
pb = new ProcessBuilder(list);
pb.directory(new File("C:\\"));
p = pb.start();
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
//echo the value of NAME
pb = new ProcessBuilder();
mand(new String[] {"CMD.exe", "/C", "echo %NAME%"});
pb.environment().put("NAME", "TEST");
p = pb.start();
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
5、獲取進程的返回值
通常,一個程序/進程在執行結束後會向操作系統返回一個整數值,0一般代表執行成功,非0表示執行出現問題。有兩種方式可以用來獲取進程的返回
值。一是利用waitFor(),該方法是阻塞的,執導進程執行完成後再返回。該方法返回一個代表進程返回值的整數值。另一個方法是調用
exitValue()方法,該方法是非阻塞的,調用立即返回。但是如果進程沒有執行完成,則拋出異常。
6、阻塞的問題
由Process代表的進程在某些平台上有時候並不能很好的工作,特別是在對代表進程的標准輸入流、輸出流和錯誤輸出進行操作時,如果使用不慎,有可能導致進程阻塞,甚至死鎖。
如果將以上事例中的從標准輸出重讀取信息的語句修改為從錯誤輸出流中讀取:stdout = new BufferedReader(new InputStreamReader(p
.getErrorStream()));
那麼程序將發生阻塞,不能執行完成,而是hang在那裡。
當進程啟動後,就會打開標准輸出流和錯誤輸出流准備輸出,當進程結束時,就會關閉他們。在以上例子中,錯誤輸出流沒有數據要輸出,標准輸出流中
有數據輸出。由於標准輸出流中的數據沒有被讀取,進程就不會結束,錯誤輸出流也就不會被關閉,因此在調用readLine()方法時,整個程序就會被阻
塞。為了解決這個問題,可以根據輸出的實際先後,先讀取標准輸出流,然後讀取錯誤輸出流。
但是,很多時候不能很明確的知道輸出的先後,特別是要操作標准輸入的時候,情況就會更為復雜。這時候可以採用線程來對標准輸出、錯誤輸出和標准輸入進行分別處理,根據他們之間在業務邏輯上的關系決定讀取那個流或者寫入數據。
針對標准輸出流和錯誤輸出流所造成的問題,可以使用ProcessBuilder的redirectErrorStream()方法將他們合二為一,這時候只要讀取標准輸出的數據就可以了。
當在程序中使用Process的waitFor()方法時,特別是在讀取之前調用waitFor()方法時,也有可能造成阻塞。可以用線程的方法來解決這個問題,也可以在讀取數據後,調用waitFor()方法等待程序結束。
總之,解決阻塞的方法應該有兩種:
(1)使用ProcessBuilder類,利用redirectErrorStream方法將標准輸出流和錯誤輸出流合二為一,在用start()方法啟動進程後,先從標准輸出中讀取數據,然後調用waitFor()方法等待進程結束。
如:import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Test3 {
public static void main(String[] args) {
try {
List list = new ArrayList();
ProcessBuilder pb = null;
Process p = null;
String line = null;
BufferedReader stdout = null;
//list the files and directorys under C:\
list.add("CMD.EXE");
list.add("/C");
list.add("dir");
pb = new ProcessBuilder(list);
pb.directory(new File("C:\\"));
//merge the error output with the standard output
pb.redirectErrorStream(true);
p = pb.start();
//read the standard output
stdout = new BufferedReader(new InputStreamReader(p
.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
int ret = p.waitFor();
System.out.println("the return code is " + ret);
stdout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
(2)使用線程import java.util.*;
import java.io.*;
class StreamWatch extends Thread {
InputStream is;
String type;
List output = new ArrayList();
boolean debug = false;
StreamWatch(InputStream is, String type) {
this(is, type, false);
}
StreamWatch(InputStream is, String type, boolean debug) {
this.is = is;
this.type = type;
this.debug = debug;
}
public void run() {
try {
PrintWriter pw = null;
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
output.add(line);
if (debug)
System.out.println(type + ">" + line);
}
if (pw != null)
pw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public List getOutput() {
return output;
}
}
public class Test5 {
public static void main(String args[]) {
try {
List list = new ArrayList();
ProcessBuilder pb = null;
Process p = null;
// list the files and directorys under C:\
list.add("CMD.EXE");
list.add("/C");
list.add("dir");
pb = new ProcessBuilder(list);
pb.directory(new File("C:\\"));
p = pb.start();
// process error and output message
StreamWatch errorWatch = new StreamWatch(p.getErrorStream(),
"ERROR");
StreamWatch outputWatch = new StreamWatch(p.getInputStream(),
"OUTPUT");
// start to watch
errorWatch.start();
outputWatch.start();
//wait for exit
int exitVal = p.waitFor();
//print the content from ERROR and OUTPUT
System.out.println("ERROR: " + errorWatch.getOutput());
System.out.println("OUTPUT: " + outputWatch.getOutput());
System.out.println("the return code is " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
7、在Java中執行Java程序
執行一個Java程序的關鍵在於:
(1)知道JAVA虛擬機的位置,即java.exe或者java的路徑
(2)知道要執行的java程序的位置
(3)知道該程序所依賴的其他類的位置
舉一個例子,一目瞭然。
(1)待執行的Java類public class MyTest {
public static void main(String[] args) {
System.out.println("OUTPUT one");
System.out.println("OUTPUT two");
System.err.println("ERROR 1");
System.err.println("ERROR 2");
for(int i = 0; i < args.length; i++)
{
System.out.printf("args[%d] = %s.", i, args[i]);
}
}
}
(2)執行該類的程序
import java.util.*;
import java.io.*;
class StreamWatch extends Thread {
InputStream is;
String type;
List output = new ArrayList();
boolean debug = false;
StreamWatch(InputStream is, String type) {
this(is, type, false);
}
StreamWatch(InputStream is, String type, boolean debug) {
this.is = is;
this.type = type;
this.debug = debug;
}
public void run() {
try {
PrintWriter pw = null;
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
output.add(line);
if (debug)
System.out.println(type + ">" + line);
}
if (pw != null)
pw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public List getOutput() {
return output;
}
}
public class Test6 {
public static void main(String args[]) {
try {
List list = new ArrayList();
ProcessBuilder pb = null;
Process p = null;
String java = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
String classpath = System.getProperty("java.class.path");
// list the files and directorys under C:\
list.add(java);
list.add("-classpath");
list.add(classpath);
list.add(MyTest.class.getName());
list.add("hello");
list.add("world");
list.add("good better best");
pb = new ProcessBuilder(list);
p = pb.start();
System.out.println(mand());
// process error and output message
StreamWatch errorWatch = new StreamWatch(p.getErrorStream(),
"ERROR");
StreamWatch outputWatch = new StreamWatch(p.getInputStream(),
"OUTPUT");
// start to watch
errorWatch.start();
outputWatch.start();
//wait for exit
int exitVal = p.waitFor();
//print the content from ERROR and OUTPUT
System.out.println("ERROR: " + errorWatch.getOutput());
System.out.println("OUTPUT: " + outputWatch.getOutput());
System.out.println("the return code is " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Ⅱ JAVA如何調用DOS命令
下面是一種比較典型的程序模式:
Process process = Runtime.getRuntime().exec(".\\p.exe");
process.waitfor( );
在上面的程序中,第一行的「.\\p.exe」是要執行的程序名,Runtime.getRuntime()返回當前應用程序的Runtime對象,該對象的exec()方法指示Java虛擬機創建一個子進程執行指定的可執行程序,並返回與該子進程對應的Process對象實例。通過Process可以控制該子進程的執行或獲取該子進程的信息。第二條語句的目的等待子進程完成再往下執行。
但在windows平台上,如果處理不當,有時並不能得到預期的結果。下面是筆者在實際編程中總結的幾種需要注意的情況:
1、執行DOS的內部命令
如果要執行一條DOS內部命令,有兩種方法。一種方法是把命令解釋器包含在exec()的參數中。例如,執行dir命令,在NT上, 可寫成exec("cmd.exe /c dir"),在windows 95/98下,可寫成「command.exe /c dir」,其中參數「/c」表示命令執行後關閉Dos立即關閉窗口。另一種方法是,把內部命令放在一個批命令my_dir.bat文件中,在Java程序中寫成exec("my_dir.bat")。如果僅僅寫成exec("dir"),Java虛擬機則會報運行時錯誤。前一種方法要保證程序的可移植性,需要在程序中讀取運行的操作系統平台,以調用不同的命令解釋器。後一種方法則不需要做更多的處理。
2、打開一個不可執行的文件
打開一個不可執行的文件,但該文件存在關聯的應用程序,則可以有兩種方式。 以打開一個word文檔a.doc文件為例,Java中可以有以下兩種寫法:
exec("start .\\a.doc");
exec(" c:\\Program Files\\Microsoft Office\\office\\winword.exe .\\a.doc");
顯然,前一種方法更為簡捷方便。
3、執行一個有標准輸出的DOS可執行程序
在windows平台上,運行被調用程序的DOS窗口在程序執行完畢後往往並不會自動關閉,從而導致Java應用程序阻塞在waitfor( )。導致該現象的一個可能的原因是,該可執行程序的標准輸出比較多,而運行窗口的標准輸出緩沖區不夠大。解決的辦法是,利用Java提供的Process類提供的方法讓Java虛擬機截獲被調用程序的DOS運行窗口的標准輸出,在waitfor()命令之前讀出窗口的標准輸出緩沖區中的內容。一段典型的程序如下:
Ⅲ java 怎麼取外部程序運行後的返回值
JAVA 中 process 類的使用
Process是一個抽象類 封裝了一個進程
創建 process
Process p = Runtime.getRuntime().exec(cmd); cmd 是字元串類型 也可以是字元串類型的數組 內容就是 命令行
Process p =ProcessBuilder.start();
Process 類提供了子進程的輸入流,子進程的輸出流子進程的輸入流,等待進程完成,檢查進程的退出狀態以及銷毀進程的方法;
創建的子進程沒有自己的控制台或終端,其所有的io操作都是通過(輸入流、輸出流、錯誤流)重定向到父進程中。
destroy()
殺掉子進程。
exitValue()
返回子進程的出口值。
InputStream getErrorStream()
獲得子進程的錯誤流。
InputStream getInputStream()
獲得子進程的輸入流。
OutputStream getOutputStream()
獲得子進程的輸出流。
waitFor()
導致當前線程等待,如果必要,一直要等到由該 Process 對象表示的進程已經終止。
-------分割線,以上來自網路-------
其中的exitValue()函數返回值就是你需要的東西。按照你的示例,return 12345,取得的值不一定等於12345,因為每個不同的shell對於程序退出的返回值是有自己的定義的,不一定是把程序return的值直接返回。可以查看各類shell的編程幫助。
Ⅳ java 鎵ц宻hell璇鍙 shell 鎵ц宱racle璇鍙
//鐢ㄦ硶錛歊untime.getRuntime.exec("鍛戒護");
Stringshpath="/test/test.sh";//紼嬪簭璺寰
Processprocess=null;
Stringmand1=鈥渃hmod777鈥+shpath;
try{
Runtime.getRuntime.exec(mand1).waitFor;
}catch(IOExceptione1){
e1.printStackTrace;
}catch(InterruptedExceptione){
e.printStackTrace;
}
Stringvar="201102";/鍙傛暟
Stringmand2=鈥/bin/sh鈥+shpath+鈥鈥+var;
Runtime.getRuntime.exec(mand2).waitFor;
// 鐢ㄦ硶錛歊untime.getRuntime.exec("鍛戒護");
String shpath="/test/test.sh"; //紼嬪簭璺寰
Process process =null;
String mand1 = 鈥渃hmod 777 鈥 + shpath;
try {
Runtime.getRuntime.exec(mand1 ).waitFor;
} catch (IOException e1) {
e1.printStackTrace;
}catch (InterruptedException e) {
e.printStackTrace;
}
String var="201102"; /鍙傛暟
String mand2 = 鈥/bin/sh 鈥 + shpath + 鈥 鈥 + var;
Runtime.getRuntime.exec(mand2).waitFor;
Stringcmdstring="chmoda+xtest.sh";
Processproc=Runtime.getRuntime.exec(cmdstring);
proc.waitFor;//闃誨烇紝鐩村埌涓婅堪鍛戒護鎵ц屽畬
cmdstring="bashtest.sh";//榪欓噷涔熷彲浠ユ槸ksh絳
proc=Runtime.getRuntime.exec(cmdstring);
//娉ㄦ剰涓嬮潰鐨勬搷浣
stringls_1;
BufferedReaderbufferedReader=newBufferedReader(newInputStreamReader(proc.getInputStream);
while紲ラ厤閾((ls_1=bufferedReader.readLine)!=null);
bufferedReader.close;
proc.waitFor;
涓轟粈璋ㄥソ涔堣佹湁涓婇潰閭f墊搷浣滃憿錛
鍘熷洜鏄錛氬彲鎵ц岀▼搴忕殑杈撳嚭鍙鑳戒細姣旇緝澶氾紝鑰岃繍琛岀獥鍙g殑杈撳嚭緙撳啿鍖烘湁闄愶紝浼氶犳垚waitFor涓鐩撮樆濉炪傝В鍐崇殑鍔炴硶鏄錛屽埄鐢↗ava鎻愪緵鐨凱rocess綾繪彁渚涚殑getInputStream,getErrorStream鏂規硶璁㎎ava鉶氭嫙鏈烘埅鑾瘋璋冪敤紼嬪簭鐨勬爣鍑嗚緭鍑恆侀敊璇杈撳嚭錛屽湪waitfor鍛戒護涔嬪墠璇繪帀杈撳嚭緙撳啿鍖轟腑鐨勫唴瀹廣
鍦╦ava涓鎵ц宻hell鑴氭湰 鐢ㄥ崠紕ф硶錛歊untime.getRuntime.exec("鍛戒護");
String shpath="/test/test.sh"; //紼嬪簭璺寰
Process process =null;
String mand1 = 鈥渃hmod 777 鈥 + shpath;
try {
Runtime.getRuntime.exec(mand1 ).waitFor;
} catch (IOException e1) {
e1.printStackTrace;
}catch (InterruptedException e) {
e.printStackTrace;
}
String var="201102"; /鍙傛暟
String mand2 = 鈥/bin/sh 鈥 + shpath + 鈥 鈥 + var;
Runtime.getRuntime.exec(mand2).waitFor;
鏍囩撅細浣滄枃緇忓吀 涓婁竴綃囷細涓涓浜哄甫澶寸殑鎴愯 涓涓鐚澶村甫澶寸殑鎴愯 涓嬩竴綃囷細鎻忓啓闀垮煄鐨勮鍙 鎻忓啓闀垮煄緹庢櫙鐨勮鍙浠ヤ笅鏄鎴戝湪鍏鍙擱」鐩涓瀹為檯搴旂敤鍒扮殑錛
/**
*鎵ц岀郴緇熷懡浠
*@time2016/10/17$17:05$
*/
{
protectedstaticLoggerlogger=LoggerFactory.getLogger(ShareDiskFileUtils.class);
;
;
static{
Stringosname=System.getProperty("os.name").toLowerCase;
isWindow=osname.contains("win");
islinux=osname.contains("linux");
logger.info("緋葷粺鐜澧冿細"+(isLinux?"Linux":"Window"));
}
/**
*鎵ц屽懡浠
*/
(Stringmand)throwsIOException,InterruptedException{
logger.info("鎵ц岀郴緇熷懡浠わ細"+mand);
Processprocess=Runtime.getRuntime.exec(getCmdArray(mand));
newStreamPrinter(process.getInputStream,logger).start;
newStreamPrinter(process.getErrorStream,logger).start;
process.waitFor;
returnprocess;
}
/**
*榪欎釜闈炲父閲嶈侊紝濡傛灉浣犵洿鎺ユ墽琛宮and錛屼細鍑虹幇涓浜涢棶棰橈紝濡傛灉鍙傛暟涓鍖呭惈涓浜涚┖鏍礆紝",'涔嬬被鐨勭壒孌婂瓧絎︼紝灝嗕細鎵ц屽け璐ワ紝
*/
privatestaticString[]getCmdArray(Stringmand){
if(isWindow){
returnnewString[]{"cmd","/c",mand};
}
if(isLinux){
returnnewString[]{"/bin/sh","-c",mand};
}
returnnewString[]{"cmd","/c",mand};
}
}
// 鐢ㄦ硶錛歊untime.getRuntime.exec("鍛戒護");
String shpath="/test/test.sh"; //紼嬪簭璺寰
Process process =null;
String mand1 = 鈥渃hmod 777 鈥 + shpath;
try {
Runtime.getRuntime.exec(mand1 ).waitFor;
} catch (IOException e1) {
e1.printStackTrace;
}catch (InterruptedException e) {
e.printStackTrace;
}
String var="201102"; /鍙傛暟
String mand2 = 鈥/bin/sh 鈥 + shpath + 鈥 鈥 + var;
Runtime.getRuntime.exec(mand2).waitFor;
濡傛灉shell鑴氭湰鍜宩ava紼嬪簭榪愯屽湪涓嶅悓鐨勬湇鍔″櫒涓婏紝鍙浠ヤ嬌鐢ㄨ繙紼嬫墽琛孡inux鍛戒護鎵ц屽寘錛屼嬌鐢╯sh2鍗忚榪炴帴榪滅▼鏈嶅姟鍣錛屽苟鍙戦佹墽琛屽懡浠ゅ氨琛屼簡錛実anymed.ssh2鐩稿叧mave閰嶇疆濡備笅錛屼綘鍙浠ヨ嚜宸辯櫨搴︽悳緔㈢浉鍏寵祫鏂欍
濡傛灉shell鑴氭湰鍜宩ava紼嬪簭鍦ㄥ悓涓鍙版湇鍔″櫒涓婏紝
榪欓噷涓嶅緱涓嶆彁鍒癹ava鐨刾rocess綾諱簡銆
process榪欎釜綾繪槸涓涓鎶借薄綾伙紝灝佽呬簡涓涓榪涚▼錛堜綘鍦ㄨ皟鐢╨inux鐨勫懡浠ゆ垨鑰卻hell鑴氭湰灝辨槸涓轟簡鎵ц屼竴涓鍦╨inux涓嬫墽琛岀殑紼嬪簭錛屾墍浠ュ簲璇ヤ嬌鐢╬rocess綾伙級銆
process綾繪彁渚涗簡鎵ц屼粠榪涚▼杈撳叆錛屾墽琛岃緭鍑哄埌榪涚▼錛岀瓑寰呰繘紼嬪畬鎴愶紝媯鏌ヨ繘紼嬬殑鎺ㄥ嚭鐘舵侊紝浠ュ強shut down鎺夎繘紼嬨
.ganymed.ssh2
ganymed-ssh2-build
210
鏈鍦版墽琛屽懡浠や唬鐮佸備笅錛
Stringshpath="/test/test.sh";//紼嬪簭璺寰
Processprocess=null;
Stringmand1=鈥渃hmod777鈥+shpath;
process=Runtime.getRuntime.exec(mand1);
process.waitFor;
1銆佹渶甯哥敤鐨勬柟娉曪細
Processp=Runtime.getRuntime.exec(SHELL_FILE_DIR+RUNNING_SHELL_FILE+
""+param1+""+param2+""+param3);
intrunnngStatus=p.waitFor;
2銆侀氳繃ProcessBuilder榪涜岃皟搴︼紝榪欑嶆柟娉曟瘮杈冪洿瑙傦紝鑰屼笖鍙傛暟鐨勮劇疆涔熸瘮杈冩柟渚匡細
ProcessBuilderpb=newProcessBuilder("./"+RUNNING_SHELL_FILE,param1,
param2,param3);
pb.directory(newFile(SHELL_FILE_DIR));
intrunningStatus=0;
Strings=null;
try{
Processp=pb.start;
try{
runningStatus=p.waitFor;
}catch(InterruptedExceptione){
e.printStackTrace;
}
}catch(IOExceptione){
e.printStackTrace;
}
if(runningStatus!=0){
}
return;
鍙傛暟璇存槑錛
RUNNING_SHELL_FILE錛氳佽繍琛岀殑鑴氭湰
SHELL_FILE_DIR錛氳佽繍琛岀殑鑴氭湰鎵鍦ㄧ殑鐩褰曪紱 褰撶劧浣犱篃鍙浠ユ妸瑕佽繍琛岀殑鑴氭湰鍐欐垚鍏ㄨ礬寰勩
runningStatus錛氳繍琛岀姸鎬侊紝0鏍囪瘑姝e父銆 璇︾粏鍙浠ョ湅java鏂囨。銆
param1, param2, param3錛氬彲浠ュ湪RUNNING_SHELL_FILE鑴氭湰涓鐩存帴閫氳繃1,1,2,$3鍒嗗埆鎷垮埌鐨勫弬鏁般
瀵逛簬絎涓涓闂棰橈細java鎶撳彇錛屽苟涓旀妸緇撴灉鎵撳寘銆傞偅涔堟瘮杈冪洿鎺ョ殑鍋氭硶灝辨槸錛宩ava鎺ユ敹鍚勭嶆秷鎮錛坉b錛宮etaq絳夌瓑錛夛紝鐒跺悗鍊熷姪浜巎storm闆嗙兢榪涜岃皟搴﹀拰鎶撳彇銆
鏈鍚庢妸鎶撳彇鐨勭粨鏋滀繚瀛樺埌涓涓鏂囦歡涓錛屽苟涓旈氳繃璋冪敤shell鎵撳寘錛 鍥炰紶銆 涔熻告湁鍚屽︿細闂錛
涓轟粈涔堜笉鐩存帴鎶妀ava璋冪敤odps鐩存帴淇濆瓨鏂囦歡錛岀瓟妗堟槸錛屾垜浠鐨勯泦緹や笉鏄痟z闆嗙兢錛岀洿鎺ヤ笂浼爋dps閫熷害寰堟湁闂棰橈紝鍥犳ゅ厛鎵撳寘姣旇緝鍚堥傘傦紙榪欓噷涓嶇籂緇撹捐′簡錛屾垜浠鍥炲埌姝i橈級
java璋冪敤shell鐨勬柟娉
閫氳繃ProcessBuilder榪涜岃皟搴
榪欑嶆柟娉曟瘮杈冪洿瑙傦紝鑰屼笖鍙傛暟鐨勮劇疆涔熸瘮杈冩柟渚匡紝 姣斿傛垜鍦ㄥ疄璺典腑鐨勪唬鐮(鎴戦殣鈃忎簡閮ㄥ垎涓氬姟浠g爜)錛
ProcessBuilderpb = new ProcessBuilder("./" + RUNNING_SHELL_FILE, param1,
param2, param3);
pb.directory(new File(SHELL_FILE_DIR));
int runningStatus = 0;
String s = null;
try {
Process p = pb.start;
try {
runningStatus = p.waitFor;
} catch (InterruptedException e) {
}
} catch (IOException e) {
}
if (runningStatus != 0) {
}
return;
榪欓噷鏈夊繀瑕佽В閲婁竴涓嬪嚑涓鍙傛暟錛
RUNNING_SHELL_FILE錛氳佽繍琛岀殑鑴氭湰
SHELL_FILE_DIR錛氳佽繍琛岀殑鑴氭湰鎵鍦ㄧ殑鐩褰曪紱 褰撶劧浣犱篃鍙浠ユ妸瑕佽繍琛岀殑鑴氭湰鍐欐垚鍏ㄨ礬寰勩
runningStatus錛氳繍琛岀姸鎬侊紝0鏍囪瘑姝e父銆 璇︾粏鍙浠ョ湅java鏂囨。銆
param1, param2, param3錛氬彲浠ュ湪RUNNING_SHELL_FILE鑴氭湰涓鐩存帴閫氳繃1,2,$3鍒嗗埆鎷垮埌鐨勫弬鏁般
鐩存帴閫氳繃緋葷粺Runtime鎵ц宻hell
榪欎釜鏂規硶姣旇緝鏆村姏錛屼篃姣旇緝甯哥敤錛 浠g爜濡備笅錛
p = Runtime.getRuntime.exec(SHELL_FILE_DIR + RUNNING_SHELL_FILE + " "+param1+" "+param2+" "+param3);
p.waitFor;
鎴戜滑鍙戠幇錛岄氳繃Runtime鐨勬柟寮忓苟娌℃湁builder閭d箞鏂逛究錛岀壒鍒鏄鍙傛暟鏂歸潰錛屽繀欏昏嚜宸卞姞絀烘牸鍒嗗紑錛屽洜涓篹xec浼氭妸鏁翠釜瀛楃︿覆浣滀負shell榪愯屻
鍙鑳藉瓨鍦ㄧ殑闂棰樹互鍙婅В鍐蟲柟娉
濡傛灉浣犺夊緱閫氳繃涓婇潰灝辮兘婊¤凍浣犵殑闇奼傦紝閭d箞鍙鑳芥槸瑕佺板佷簡銆備綘浼氶亣鍒頒互涓嬫儏鍐點
娌℃潈闄愯繍琛
榪欎釜鎯呭喌鎴戜滑鍥㈤槦鐨勬湵涓滄柟灝遍亣鍒頒簡錛 鍦ㄥ仛DTS榪佺Щ鐨勮繃紼嬩腑錛岃佹墽琛屽寘閲岄潰鐨剆hell鑴氭湰錛 瑙e帇鍑烘潵浜嗕箣鍚庯紝鍙戠幇鎵ц屼笉浜嗐 閭d箞灝辨寜鐓т笂闈㈢殑鏂規硶鎺堟潈鍚
java榪涜屼竴鐩寸瓑寰卻hell榪斿洖
榪欎釜闂棰樹及璁℃洿鍔犵粡甯擱亣鍒般 鍘熷洜鏄錛 shell鑴氭湰涓鏈塭cho鎴栬卲rint杈撳嚭錛 瀵艱嚧緙撳啿鍖鴻鐢ㄥ畬浜! 涓轟簡閬垮厤榪欑嶆儏鍐碉紝 涓瀹氳佹妸緙撳啿鍖鴻諱竴涓嬶紝 濂藉勫氨鏄錛屽彲浠ュ箂hell鐨勫叿浣撹繍琛岀姸鎬佽繘琛宭og鍑烘潵銆 姣斿備笂闈㈡垜鐨勪緥瀛愪腑鎴戜細鍙樻垚錛
ProcessBuilderpb = new ProcessBuilder("./" + RUNNING_SHELL_FILE, keyword.trim,
taskId.toString, fileName);
pb.directory(new File(CASPERJS_FILE_DIR));
int runningStatus = 0;
String s = null;
try {
Process p = pb.start;
BufferedReaderstdInput = new BufferedReader(new InputStreamReader(p.getInputStream));
BufferedReaderstdError = new BufferedReader(new InputStreamReader(p.getErrorStream));
while ((s = stdInput.readLine) != null) {
LOG.error(s);
}
while ((s = stdError.readLine) != null) {
LOG.error(s);
}
try {
runningStatus = p.waitFor;
} catch (InterruptedException e) {
}
璁板緱鍦╯tart涔嬪悗錛 waitFor錛堬級涔嬪墠鎶婄紦鍐插尯璇誨嚭鏉ユ墦log錛 灝卞彲浠ョ湅鍒頒綘鐨剆hell涓轟粈涔堜細娌℃湁鎸夌収棰勬湡榪愯屻 榪欎釜榪樻湁涓涓濂藉勬槸錛屽彲浠ヨ籹hell閲岄潰杈撳嚭鐨勭粨鏋滐紝 鏂逛究java浠g爜榪涗竴姝ユ搷浣溿
涔熻鎬綘榪樹細閬囧埌榪欎釜闂棰橈紝鏄庢槑鎵嬪伐鍙浠ヨ繍琛岀殑鍛戒護錛宩ava璋冪敤鐨剆hell涓鏌愪竴浜涘懡浠ゅ眳鐒朵笉鑳芥墽琛岋紝鎶ラ敊錛氬懡浠や笉瀛樺湪錛
姣斿傛垜鍦ㄤ嬌鐢╟asperjs鐨勬椂鍊欙紝鎵嬪伐鍘繪墽琛宻hell鏄庢槑鏄鍙浠ユ墽琛岀殑錛屼絾鏄痡ava璋冪敤鐨勬椂鍊欙紝鍙戠幇鎬繪槸鍑洪敊銆
閫氳繃璇誨彇緙撳啿鍖哄氨鑳藉彂鐜伴敊璇鏃ュ織浜嗐 鎴戝彂鐜板嵆渚胯嚜宸辨妸瀹夎呯殑casperjs鐨刡in宸茬粡鍔犲叆浜唒ath涓錛/etc/profile,
鍚勭峛ashrc涓錛夎繕涓嶅熴 姣斿傦細
exportNODE_HOME="/home/admin/node"
exportCASPERJS_HOME="/home/admin/casperjs"
exportPHANTOMJS_HOME="/home/admin/phantomjs"
exportPATH=$PATH:$JAVA_HOME/bin:/root/bin:$NODE_HOME/bin:$CASPERJS_HOME/bin:$PHANTOMJS_HOME/bin
鍘熸潵鏄鍥犱負java鍦ㄨ皟鐢╯hell鐨勬椂鍊欙紝榛樿ょ敤鐨勬槸緋葷粺鐨/bin/涓嬬殑鎸囦護銆傜壒鍒鏄浣犵敤root鏉冮檺榪愯岀殑鏃跺欍 榪欐椂鍊欙紝浣犺佸湪/bin涓嬪姞杞閾句簡銆傞拡瀵規垜涓婇潰鐨勪緥瀛愶紝灝辮佸湪/bin涓嬪姞杞閾撅細
ln -s /home/admin/casperjs/bin/casperjscasperjs;
ln -s /home/admin/node/bin/nodenode;
ln -s /home/admin/phantomjs/bin/phantomjsphantomjs;
榪欐牱錛岄棶棰樺氨鍙浠ヨВ鍐充簡銆
濡傛灉鏄閫氳繃java璋冪敤shell榪涜屾墦鍖咃紝閭d箞瑕佹敞鎰忚礬寰勭殑闂棰樹簡
鍥犱負shell閲岄潰tar鐨勫帇緙╁拰瑙e帇鍙涓嶈兘鐩存帴鍐欙細
tar -zcf /home/admin/data/result.tar.gz /home/admin/data/result
鐩存帴緇欎綘鎶ラ敊錛屽洜涓簍ar鐨勫帇緙╂簮蹇呴』鍒拌礬寰勪笅闈錛 鍥犳ゅ彲浠ュ啓鎴
tar -zcf /home/admin/data/result.tar.gz -C /home/admin/data/ result
濡傛灉鎴戠殑shell鏄鍦╦ar鍖呬腑鎬庝箞鍔烇紵
絳旀堟槸錛氳В鍘嬪嚭鏉ャ傚啀鎸夌収涓婇潰鎸囩ず榪涜屾搷浣溿傦紙1錛夋壘鍒拌礬寰
String jarPath = findClassJarPath(ClassLoaderUtil.class);
JarFiletopLevelJarFile = null;
try {
topLevelJarFile = new JarFile(jarPath);
Enumeration entries = topLevelJarFile.entries;
while (entries.hasMoreElements) {
JarEntryentry = entries.nextElement;
if (!entry.isDirectory entry.getName.endsWith(".sh")) {
瀵逛綘鐨剆hell鏂囦歡榪涜屽勭悊
}
}
瀵規枃浠跺勭悊鐨勬柟娉曞氨綆鍗曚簡錛岀洿鎺touch涓涓涓存椂鏂囦歡錛岀劧鍚庢妸鏁版嵁嫻佸啓鍏ワ紝浠g爜錛
FileUtils.touch(tempjline);
tempjline.deleteOnExit;
FileOutputStreamfos = new FileOutputStream(tempjline);
IOUtils.(ClassLoaderUtil.class.getResourceAsStream(r), fos);
fos.close;
棣栧厛浣犲彲浠ョ櫨搴︽悳涓涓 java Process 綾葷殑鐢ㄦ硶錛屽緢澶氬崥鏂囬兘鏈夎茶В銆
鍙﹀栨垜琛ュ厖涓涓嬫垜鍐嶄嬌鐢ㄨ繃紼嬩腑鐨勪竴浜涚偣錛
process = Runtime.getRuntime.exec(new String[]{"/bin/sh","-c",shellContext});
鍏朵腑 shellContext 鏄痵hel鑴氭湰瀛楃︿覆
榪欏彞鎻愪氦鐨勬椂鍊欙紝涓嶅皯鍗氭枃 exec涓鏄鐩存帴鎻愪氦shellContext銆
浣嗘槸瀵逛簬涓浜涘満鏅涓嶉傜敤錛屽彇鍑烘潵鏁版嵁璺熺洿鎺ヨ繍琛宻hell鑴氭湰鏈夊樊寮傦紝鍙浠ユ敼鎴愭垜榪欑嶅啓娉曘
鏍囩撅細浣滄枃緇忓吀 涓婁竴綃囷細涓涓浜哄甫澶寸殑鎴愯 涓涓鐚澶村甫澶寸殑鎴愯 涓嬩竴綃囷細鎻忓啓闀垮煄鐨勮鍙 鎻忓啓闀垮煄緹庢櫙鐨勮鍙Ⅳ 如何用Java關閉一個進程
解決這個問題,要看這個進程是java程序自定義的進程,還是操作系統的進程,操作系統的進程,又可以分為windows進程和Linux進程
一、針對操作系統的進程:
1,首先java用戶,要具有操作進程的許可權
2. 針對windows操作系統的進程,比如QQ進程:
Stringcommand="taskkill/f/imQQ.exe";
Runtime.getRuntime().exec(command);
其中:taskkill 是命令名稱,/f /im 是參數,QQ.exe是進程的可執行文件。
3.針對Linux操作系統
Stringcommand="kill/f/imQQ.exe";
Runtime.getRuntime().exec(command);
二、在Java程序中自定義的進程
思路:在線程中設置一個標志變數,當這個變數的值在外界被改變的時候,有機會結束運行的線程
publicclassT{
publicstaticvoidmain(String[]args){
//啟動線程
MyThreadthread=newMyThread();
newThread(thread).start();
//你的其它的工作,此時線程在運行中
//你不想讓線程幹活了,停掉它
//注意,這只是一個標志,具體線程何時停,並不能精確控制
thread.allDone=true;
}
}
{
booleanvolatileallDone=false;
publicvoidrun(){
//每次循環都檢測標志
//如果設置停止標志時已經在循環里
//則最長需要等待一個循環的時間才能終止
while(!allDone){
//循環里的工作
}
}
}
Ⅵ java中如何執行命令行語句
可以使用java.lang.Process和java.lang.Runtime實現,下面展示兩個例子,其它用法請查閱資料:
1、執行ping命令:
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
publicclassProcessTest{
publicstaticvoidmain(String[]args){
BufferedReaderbr=null;
try{
Stringcmd="ping127.0.0.1";
//執行dos命令並獲取輸出結果
Processproc=Runtime.getRuntime().exec(cmd);
br=newBufferedReader(newInputStreamReader(proc.getInputStream(),"GBK"));
Stringline;
while((line=br.readLine())!=null){
System.out.println(line);
}
proc.waitFor();
}catch(IOExceptione){
e.printStackTrace();
}catch(InterruptedExceptione){
e.printStackTrace();
}finally{
if(br!=null){
try{
br.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
}
2、打開瀏覽器並跳轉到網路首頁:
importjava.io.IOException;
publicclassProcessTest{
publicstaticvoidmain(String[]args){
try{
StringexeFullPathName="C:/ProgramFiles/InternetExplorer/IEXPLORE.EXE";
Stringmessage="www..com";
String[]cmd={exeFullPathName,message};
Processproc=Runtime.getRuntime().exec(cmd);
}catch(IOExceptione){
e.printStackTrace();
}
}
}