我试图连接到主机,然后使用更改用户“苏 - 约翰”,然后执行命令约翰。 是否有可能只使用JSch?
问题是,我以后创建一个会话,并打开通道,并执行上述命令应该要求密码,但没有任何反应。
这就是我如何连接到远程机器:
String address = "myremote.computer.com";
JSch jsch = new JSch();
String user = "tom";
String host = address;
String password = "l33tpaSSw0rd";
Session session = jsch.getSession( user, host, 22 );
java.util.Properties config = new java.util.Properties();
config.put( "StrictHostKeyChecking", "no" );
session.setConfig( config );
session.setPassword( password );
session.connect();
然后,我通过执行命令runSshCommand()
方法,该方法是这样的:
try
{
Channel channel = session.openChannel( "exec" );
channel.setInputStream( null );
channel.setOutputStream( System.out );
( (ChannelExec) channel ).setCommand( command );
channel.connect();
InputStream in = channel.getInputStream();
byte[] tmp = new byte[1024];
while ( true )
{
while ( in.available() > 0 )
{
int i = in.read( tmp, 0, 1024 );
if ( i < 0 )
{
break;
}
System.out.print( new String( tmp, 0, i ) );
}
if ( channel.isClosed() )
{
break;
}
try
{
Thread.sleep( 1000 );
}
catch ( Exception ee )
{
}
}
channel.disconnect();
}
catch ( Exception e )
{
e.printStackTrace();
}
我一定要创建另一个通道,当我改变的用户,或如何使这项工作?
因为如果我使用
runSshCommand("su - john",session);
runSshCommand("tail -1 ~/mylog.log",session);
它只是执行“苏”命令,但它并没有完成用户的变化和事后执行“尾巴”将导致一个错误,因为“汤姆”还没有得到该文件:/
基本上,我想我的应用程序连接到本机,更改用户,读取一个文件,并返回数据。 任何人都可以提供一些线索吗?
You have several problems here.
First, each channel in a SSH connection is independent of the other ones, and the command in each exec channel is executed in its own shell (command line interpreter). So any changes you are doing in one channel have no effect at all to the other channels. You also can't do stuff like this:
runSshCommand("cd Documents", session);
runSshCommand("ls -l", session);
(Actually you can do this, but it will not show the contents of the Documents
directory, but of the home directory.)
For cd
, you can work around by passing both commands as one "command", to be used in the same exec
channel:
runSshCommand("cd Documents; ls -l");
(Instead of the ;
you can also use a line break \n
to separate the commands, or whatever else your shell accepts.)
For su
this will not work, where we come to the second problem.
su
is not a command which changes the state of the current shell (like cd
), but a command which opens a new shell inside the existing one. It will only return to the outer shell when you leave the shell started by su
(e.g. by exit
, logout
or end-of-file), and then you are again the same user as before.
To pass commands to the "inner shell", you'll have to pass them to the shells input. Or use the -c
(--command
) argument of su
:
runSshCommand("su -c 'tail -1 ~/mylog.log' - john ",session);
You might then run in the third problem: su
will ask for john's password, and might refuse to read it from the standard input, but try to read it from the terminal. And your channel has no pseudo-terminal. You can try to use cannel.setPty(true)
and then actually write your password to the output stream, though I'm not sure that this will work.
Alternatives: Instead of su -c
you can use sudo
, which can be configured not to ask for a password for certain commands and users (otherwise you'll have the same terminal problem again). Or you could directly log in as john
, or make the logfile readable for tom. (Also, I hope your real password is better than the one in your source code.)