JSchを使用してJavaからリモートUnixホストに正常に接続し、いくつかの基本的なコマンドを実行したり、ファイルを表示したりすることができます。
問題は環境の設定から始まります...あるコマンドで変数をエクスポートすると、別のシェルで実行されているかのように、次のコマンドでは表示されません。私がやりたいのは、同じシェルで実行されている複数のコマンドをエミュレートすることです。
これが私のexecuteCommandメソッドです。これには、 openHostSession(下記)によって作成された以前に作成されたcom.jcraft.jsch.Sessionが必要です。
public static void executeCommand(Session sess, String cmd, PrintStream pstream)
{
System.out.println("About to execute <" + cmd + ">");
try
{
ChannelExec chnl = (ChannelExec)sess.openChannel("exec");
chnl.setInputStream(null);
chnl.setErrStream(System.err);
chnl.setCommand(cmd);
InputStream in = chnl.getInputStream();
chnl.connect();
byte[] tmp=new byte[1024];
while(true)
{
while(in.available() > 0)
{
int i = in.read(tmp, 0, 1024);
if(i < 0) break;
pstream.print(new String(tmp, 0, i));
}
if(chnl.isClosed())
{
pstream.println("exit-status: " + chnl.getExitStatus());
break;
}
try
{
Thread.sleep(1000);
}
catch(Exception ee){}
}
chnl.disconnect();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
ここにopenHostSessionがあります:
public static Session openHostSession(String host, String user, String passwd)
{
JSch jsch=new JSch();
Session rslt = null;
try
{
rslt = jsch.getSession(user, host, 22);
rslt.setConfig("StrictHostKeyChecking", "no");
rslt.setPassword(passwd);
rslt.connect(30000);
}
catch(JSchException jschEx)
{
jschEx.printStackTrace();
}
return rslt;
}
クライアントコード
cmd = "export XVAR=abc";
SshUtil.executeCommand(sess, cmd, System.out);
cmd = "echo $XVAR";
SshUtil.executeCommand(sess, cmd, System.out);
出力:
About to execute <export XVAR=abc>
exit-status: 0
About to execute <echo $XVAR>
exit-status: 0
システムレベルのenv変数を確認できます。例:
cmd = "echo $SHELL";
SshUtil.executeCommand(sess, cmd, System.out);
戻り値
About to execute <echo $SHELL>
/bin/ksh
終了ステータス:0
.profile(cmd = ". ./.profile";)
.profile内に設定された変数は次のコマンドでは表示されません。コマンドは同じセッションを共有しますが、それぞれが独自のチャネルを開きます。チャネルを共有しようとしましたが、うまくいきませんでした。