ちょい仕事で Java で SSH/SCP を実行するライブラリがあるといいな的展開があって、ちょっと調べたら良さそうなのがあったので、メモ。
- Ganymed SSH-2 for Java
- http://www.ganymed.ethz.ch/ssh2/
最初読めなかったけど、「ガニメデ」ですね。
昔は Java から scp を叩ける良いライブラリがまだ無く、結局そのときは外部コマンド実行によって実現したものだが、今はこんないいものがあるんやね。
外部コマンド実行だと、どうしても
- コマンドごとに認証(よってパフォーマンス悪し)
- 若干不安定(よってエラー処理が面倒)
- 標準入出力周りの処理をしっかりする必要がある(よってコーディング量が増える)
- パスワード/パスフレーズが使えない(よってパスフレーズを空で鍵ペアを作らないといけない)
という何重苦なんだか、という状態に陥るのだが、 Ganymed ならずいぶん改善されそうである。
早速 scp のテストコードを組んでみた。
エラー処理は省いているとはいえ、こんなに短く書けるなんて、外部コマンド実行でのあの苦労は何だったんだー! と海に向かって叫びたいところである。
import java.io.IOException; import ch.ethz.ssh2.*; public class ScpTest { private static final String hostname = "ホスト名"; private static final String userid = "ユーザ名"; private static final String password = "パスワード"; public static void main(String[] arg) { try { ScpTest test = new ScpTest(); test.doProc(); } catch (IOException ex) {ex.printStackTrace();} } public void doProc() throws IOException { // connect & login Connection conn = new Connection(hostname); ConnectionInfo info = conn.connect(); boolean result = conn.authenticateWithPassword(userid, password); if (result) { // "abc<CR><LF>" private byte[] b = {48, 49, 50, 13, 10}; // scp SCPClient scp = conn.createSCPClient(); scp.put(b, "testtest1.txt", "~/"); scp.put(b, "testtest2.txt", "~/"); scp.put(b, "testtest3.txt", "~/"); } conn.close(); } }
連続での scp 転送も問題なし(実は1回目より2回目・3回目の方が実行時間がかかる。内部で呼び出している Connect.openSession() の2回目以降が遅いのか??)。
例外は全て IOException。
これは好みもあるだろうが、できれば独自に Exception クラスを定義して欲しかった。
コマンド実行時は都度 OpenSession() を呼ぶ必要があるが、また今度。
続きの記事一覧
- (2) Ganymed でコマンド実行
- http://d.hatena.ne.jp/n_shuyo/20060707/1152290107
- (3) Ganymed で複数のコマンド実行
- http://d.hatena.ne.jp/n_shuyo/20060714/1152899236
- (4) Jsh 紹介
- http://d.hatena.ne.jp/n_shuyo/20060814/1155547412
- (5) Jsh でコマンド実行
- http://d.hatena.ne.jp/n_shuyo/20060815/1155613198
- (6) Jsh で sftp
- http://d.hatena.ne.jp/n_shuyo/20060820/1156054408
- (7) Jsh で sftp の解説
- http://d.hatena.ne.jp/n_shuyo/20060908/1157655411