你得明白,啟動遠程的服務,首先得連接到伺服器上去。
下面有兩種方法:1、通過自定義程序;
2、使用現成的telnet或ssh(推薦)
方法1、首先得看linux伺服器的限制,如果伺服器允許自定義的登錄,
並且你在伺服器上運行了一個監聽某埠(如1234)的程序,
寫一個client端,用socket連接上去,就可以執行了。
方法2、如果伺服器支持ssh或者telnet登錄,且
允許遠程執行腳本的話,可以直接登錄進去(當然這算是
使用現成的程序吧,ssh更安全,不過或許不是你想要的。)
有現成的ssh服務,直接使用就是了,自己寫的肯定沒這個安全~~
要用java的話,應該也有現成的ssh客戶端---
❷ java程序執行linux命令
首先確保Linux開啟sshd服務,並支持遠程SSH連接。java程序使用jsch框架登錄Linux,執行命令。
protected void creation() throws Exception {
JSch jsch = new JSch();
session = jsch.getSession(userName, host, port);
session.setPassword(password);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setTimeout(CONNECT_TIMEOUT);
session.setConfig("PreferredAuthentications", "password,keyboard-interactive");
session.setServerAliveInterval(1000 * 60 * 2);
session.connect();
}
public String sendCommand(String command) throws Exception {
if(!isConnected())
throw new JSchException("Session is not connected, command exec faild.");
final ChannelExec exec = (ChannelExec)session.openChannel("exec");
ByteArrayOutputStream out = new ByteArrayOutputStream();
exec.setCommand(command);
exec.setOutputStream(out);
exec.setExtOutputStream(out);
exec.connect();
final Thread thread = new Thread() {
public void run() {
while(!exec.isEOF()) {
try { Thread.sleep(500L); } catch(Exception e) {}
}
}
};
thread.setDaemon(true);
thread.start();
thread.join(EXEC_TIMEOUT);
thread.interrupt();
if(thread.isAlive()) {
throw new JSchException("Exec Time Out Error");
} else {
try {
exec.disconnect();
out.close();
} catch (Exception e) {
}
byte[] lens = out.toByteArray();
String result = new String(lens, charset);
if(result.startsWith("bash") && result.indexOf("command not found") != -1)
return "";
return result;
}
}
❸ 如何在java程序中調用linux命令或者shell腳本
做到這,主要依賴2個類:Process和Runtime。
首先看一下Process類:
ProcessBuilder.start() 和 Runtime.exec 方法創建一個本機進程,並返回 Process 子類的一個實例,
該實例可用來控制進程並獲得相關信息。Process 類提供了執行從進程輸入、執行輸出到進程、等待進程完成、
檢查進程的退出狀態以及銷毀(殺掉)進程的方法。
創建進程的方法可能無法針對某些本機平台上的特定進程很好地工作,比如,本機窗口進程,守護進程,Microsoft Windows
上的 Win16/DOS 進程,或者 shell 腳本。創建的子進程沒有自己的終端或控制台。它的所有標准 io(即 stdin、stdout 和 stderr)
操作都將通過三個流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父進程。
父進程使用這些流來提供到子進程的輸入和獲得從子進程的輸出。因為有些本機平台僅針對標准輸入和輸出流提供有限的緩沖區大小,
如果讀寫子進程的輸出流或輸入流迅速出現失敗,則可能導致子進程阻塞,甚至產生死鎖。
當沒有 Process 對象的更多引用時,不是刪掉子進程,而是繼續非同步執行子進程。
對於帶有 Process 對象的 Java 進程,沒有必要非同步或並發執行由 Process 對象表示的進程。
特別需要注意的是:
1,創建的子進程沒有自己的終端控制台,所有標注操作都會通過三個流
(getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父進程(父進程可通過這些流判斷子進程的執行情況)
2,因為有些本機平台僅針對標准輸入和輸出流提供有限的緩沖區大小,如果讀寫子進程的輸出流或輸入流迅速出現失敗,
則可能導致子進程阻塞,甚至產生死鎖
abstract void destroy()
殺掉子進程。
abstract int exitValue()
返回子進程的出口值。根據慣例,值0表示正常終止。
abstract InputStream getErrorStream()
獲取子進程的錯誤流。
abstract InputStream getInputStream()
獲取子進程的輸入流。
abstract OutputStream getOutputStream()
獲取子進程的輸出流。
abstract int waitFor()
導致當前線程等待,如有必要,一直要等到由該 Process 對象表示的進程已經終止。
如果已終止該子進程,此方法立即返回。如果沒有終止該子進程,調用的線程將被阻塞,直到退出子進程。
特別需要注意:如果子進程中的輸入流,輸出流或錯誤流中的內容比較多,最好使用緩存(注意上面的情況2)
再來看一下Runtime類:
每個Java應用程序都有一個Runtime類實例,使應用程序能夠與其運行的環境相連接。可以通過getRuntime方法獲取當前運行時環境。
應用程序不能創建自己的Runtime類實例。
介紹幾個主要方法:
Process exec(String command)
在單獨的進程中執行指定的字元串命令。
Process exec(String command, String[] envp)
在指定環境的單獨進程中執行指定的字元串命令。
Process exec(String command, String[] envp, File dir)
在有指定環境和工作目錄的獨立進程中執行指定的字元串命令。
Process exec(String[] cmdarray)
在單獨的進程中執行指定命令和變數。
Process exec(String[] cmdarray, String[] envp)
在指定環境的獨立進程中執行指定命令和變數。
Process exec(String[] cmdarray, String[] envp, File dir)
在指定環境和工作目錄的獨立進程中執行指定的命令和變數。
command:一條指定的系統命令。
envp:環境變數字元串數組,其中每個環境變數的設置格式為name=value;如果子進程應該繼承當前進程的環境,則該參數為null。
dir:子進程的工作目錄;如果子進程應該繼承當前進程的工作目錄,則該參數為null。
cmdarray:包含所調用命令及其參數的數組。
以下為示例(要打成可執行jar包扔到linux下執行):
public class test {
public static void main(String[] args){
InputStream in = null;
try {
Process pro = Runtime.getRuntime().exec(new String[]{"sh",
"/home/test/test.sh","select admin from M_ADMIN",
"/home/test/result.txt"});
pro.waitFor();
in = pro.getInputStream();
BufferedReader read = new BufferedReader(new InputStreamReader(in));
String result = read.readLine();
System.out.println("INFO:"+result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
在這用的是Process exec(String[] cmdarray)這個方法
/home/test/test.sh腳本如下:
#!/bin/sh
#查詢sql
SQL=$1
#查詢結果保存文件
RESULT_FILE=$2
#資料庫連接
DB_NAME=scott
DB_PWD=tiger
DB_SERVER=DB_TEST
RESULT=`sqlplus -S ${DB_NAME}/${DB_PWD}@${DB_SERVER}<< !
set heading off
set echo off
set pages 0
set feed off
set linesize 3000
${SQL}
/
commit
/
!`
echo "${RESULT}" >> ${RESULT_FILE}
echo 0;
特別需要注意的是,當需要執行的linux命令帶有管道符時(例如:ps -ef|grep java),用上面的方法是不行的,解決方式是將需要執行的命令作為參數傳給shell
public class Test {
public static void main(String[] args) throws Exception{
String[] cmds = {"/bin/sh","-c","ps -ef|grep java"};
Process pro = Runtime.getRuntime().exec(cmds);
pro.waitFor();
InputStream in = pro.getInputStream();
BufferedReader read = new BufferedReader(new InputStreamReader(in));
String line = null;
while((line = read.readLine())!=null){
System.out.println(line);
}
}
}
PS:
Runtime.getRuntime().exec()這種調用方式在java虛擬機中是十分消耗資源的,即使命令可以很快的執行完畢,頻繁的調用時創建進程消耗十分客觀。
java虛擬機執行這個命令的過程是,首先克隆一條和當前虛擬機擁有一樣環境變數的進程,再用這個新的進程執行外部命令,最後退出這個進程。頻繁的創建對CPU和內存的消耗很大。
❹ 如何用Java寫代碼連上Linux主機去在主機上執行命令
其實不難,給你思路如下:
第一,你需要在遠程Linux主機上面裝好一個接收端程序,這個程序可以是java寫的,也可以是C語言寫的,都無所謂,因為網路介面是一樣的,都是socket。
如果你要用java寫,那需要在Linux上面把jdk裝上,推薦你用C寫,更容易操作linux執行cmd命令.
假設從主機A,檢查主機B上的進程,
需要在主機B上建立檢查用戶,例如叫x,
並設置通過public key認證登錄SSH,不會可以google搜一下,
然後,在A機器上執行:
ssh x@B ~/command.sh > result.txt
command.sh就是B機器上放置在x目錄下的腳本。
輸出結果應該是寫到了result.txt
或者另一種寫法
result=`ssh x@B ~/command.sh`
結果直接保存到result變數中了。
暫時沒有linux環境,所以沒有實際測試,你自己試試吧
❺ 怎麼用java代碼運行linux命令
以下方法支持Linux和windows兩個系統的命令行調用。還用到了apache的lang工具包commons-lang3-3.1.jar來判斷操作系統類型、也用到了和log4j-1.2.16.jar來列印日誌。至於rm -rf 是否能成功刪除文件,可以手動去調用命令行試試。
privateStringcallCmd(Stringcmd)throwsInterruptedException,UnHandledOSException,ExecuteException{
if(SystemUtils.IS_OS_LINUX){
try{
//使用Runtime來執行command,生成Process對象
Processprocess=Runtime.getRuntime().exec(
newString[]{"/bin/sh","-c",cmd});
intexitCode=process.waitFor();
//取得命令結果的輸出流
InputStreamis=process.getInputStream();
//用一個讀輸出流類去讀
InputStreamReaderisr=newInputStreamReader(is);
//用緩沖器讀行
BufferedReaderbr=newBufferedReader(isr);
Stringline=null;
StringBuildersb=newStringBuilder();
while((line=br.readLine())!=null){
System.out.println(line);
sb.append(line);
}
is.close();
isr.close();
br.close();
returnsb.toString();
}catch(java.lang.NullPointerExceptione){
System.err.println("NullPointerException"+e.getMessage());
logger.error(cmd);
}catch(java.io.IOExceptione){
System.err.println("IOException"+e.getMessage());
}
thrownewExecuteException(cmd+"執行出錯!");
}
if(SystemUtils.IS_OS_WINDOWS){
Processprocess;
try{
//process=newProcessBuilder(cmd).start();
String[]param_array=cmd.split("[\s]+");
ProcessBuilderpb=newProcessBuilder(param_array);
process=pb.start();
/*process=Runtime.getRuntime().exec(cmd);*/
intexitCode=process.waitFor();
InputStreamis=process.getInputStream();
InputStreamReaderisr=newInputStreamReader(is);
BufferedReaderbr=newBufferedReader(isr);
Stringline;
StringBuildersb=newStringBuilder();
while((line=br.readLine())!=null){
System.out.println(line);
sb.append(line);
}
is.close();
isr.close();
br.close();
returnsb.toString();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
thrownewExecuteException(cmd+"執行出錯!");
}
thrownewUnHandledOSException("不支持本操作系統");
}