반응형

SSH 연결 후 Shell 명령 및 Sftp 전송하기

pom.xml

<!-- SSH -->
<dependency>
  <groupId>com.jcraft</groupId>
  <artifactId>jsch</artifactId>
  <version>0.1.55</version>
</dependency>

 

SSHUtil.java

import java.io.ByteArrayOutputStream;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;

public class SSHUtil {
	
	private Session session;
	private Channel channel;
	private ChannelExec channelExec;
	private ChannelSftp channelSftp;
	private long percent = 0;
	
	public SSHUtil() {}
	
	public SSHUtil(String name, String password, String host, int port) {
		this.connect(name, password, host, port);
	}
	
	public SSHUtil connect(String name, String password, String host, int port) {
		try {
			session = new JSch().getSession(name, host, port);
			session.setPassword(password);
			session.setConfig("StrictHostKeyChecking", "no");
			session.connect();
		} catch (JSchException e) {
			e.printStackTrace();
		}
		
		return this;
	}
	
	public String command(String command) {
		if(session == null) {
			return "ssh 연결이 되지 않았습니다.";
		}else if(command == null || command.trim().equals("")) {
			return "명령어를 입력해주세요.";
		}
		
		String responseString = "";
		try {
			ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
			
			channelExec = (ChannelExec) session.openChannel("exec");
			channelExec.setCommand(command);
			channelExec.setOutputStream(responseStream);
			channelExec.connect();
	        while (channelExec.isConnected()) {
	            Thread.sleep(100);
	        }
	        
	        responseString = new String(responseStream.toByteArray());
		} catch (JSchException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
	        this.disConnect();
	    }
		return responseString;
	}
	
	public String fileSend(String OutPutPath, String DestinyPath) {
		percent = 0; //초기화
		if(session == null) {
			return "ssh 연결이 되지 않았습니다.";
		}else if(OutPutPath == null || DestinyPath == null) {
			return "경로가 정상적으로 등록되지 않았습니다.";
		}
		
		try {
			channelSftp = (ChannelSftp) session.openChannel("sftp");
			channelSftp.connect();
			channelSftp.put(OutPutPath, DestinyPath, new SystemOutProgressMonitor());
		} catch (JSchException e) {
			e.printStackTrace();
		} catch (SftpException e) {
			e.printStackTrace();
		} finally {
			this.disConnect();
		}
		return "정상적으로 전송하였습니다.";
	}
	
	public void disConnect() {
		if (session != null) {
            session.disconnect();
        }
        if (channel != null) {
            channel.disconnect();
        }
        if(channelExec != null) {
        	channelExec.disconnect();
        }
        if(channelSftp != null) {
        	channelSftp.disconnect();
        }
	}
	
	public long getSendPercent() {
		if(percent >= 100) {
			percent = 0;
			return (long)100;
		}
		return percent;
	}
	
	class SystemOutProgressMonitor implements SftpProgressMonitor {
		private long fileSize = 0;
		private long sendFileSize = 0;
		
		@Override
		public void init(int op, String src, String dest, long max) {
			this.fileSize = max;
			System.out.println("Starting : " + op + "  " + src + " -> " + dest + " total : " + max);
		}

		@Override
		public boolean count(long count) {
			this.sendFileSize += count;
			long p = this.sendFileSize * 100 / this.fileSize;
			if(p > percent) {
				percent++;
			}
			return true;
		}

		@Override
		public void end() {
			System.out.println("Finished!");
		}
	}
}

connect : 입력 파라미터값에 따른 연결 처리

command : 파라미터값으로 명령어 처리 및 결과 받기

fileSend : 읽어들일 경로, 전송할 경로 옵션에 따라 전송처리

disConnect : SSH 연결 종료

getSendPercent : 파일전송되고 있는 퍼센트값 return

SystemOutProgressMonitor : 내부 클래스로 SftpProgressMonitor 인터페이스를 상속받고 init, count, end 메소드에 따라 동작한다. 파일 전송시 put메소드에서 3번째 파라미터값에서 new 생성자로 사용된다.

 

상황에 맞춰 사용하시면 됩니다.

 

 

 

반응형