我有一个非常基本的Java程序,该程序使用Jsch库自动执行位于Unix框中的某些Shell脚本。
为了自动执行这些shell脚本,需要执行以下步骤:
john
登录Unix框simba
OutputStream
提供此新用户的凭据,绕过cli
的输入提示,然后使用os.flush()
刷新它whoami
命令检查用户切换是否发生我编写了以下程序来实现此功能,但是正如您在控制台输出中看到的那样,用户切换没有发生,第二条whoami
命令为我提供了相同的用户名(即:john
)< / p>
我想到的另一个问题是,对于cli
,su -
,logout
等没有bash
输出的命令,我应该怎么做。当什么也不会返回时,在无限while(true)
循环中等待输出是没有意义的。
请指导。
当前控制台输出
Connecting SSH to my-unix-box.net - Please wait for few seconds...
Connected!
Executing command: whoami
john
Executing command: su - simba
Setting suPasswd now....
Executing command: whoami
john //WRONG: SHOULD BE "simba"
Disconnected channel and session
Process finished with exit code 0
SSHConn.java
public class SSHConn {
static Session session;
static String[] commands = {"whoami", "su - simba", "whoami"};
public static void main(String[] args) throws Exception {
open();
runCmd(commands);
close();
}
public static void runCmd(String[] commands) throws JSchException, IOException {
for (String cmd : commands) {
System.out.println("Executing command: " + cmd);
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(cmd);
InputStream in = channel.getInputStream();
OutputStream out = channel.getOutputStream();
channel.connect();
//passing creds only when you switch user
if (cmd.startsWith("su -")) {
System.out.println("Setting suPasswd now....");
out.write((Constants.suPasswd + "\n").getBytes());
out.flush();
}
System.out.println("Flushed suPasswd to cli...");
//capture output that we receive from cli (note: some commands such as "su -" does not return anything)
if (!cmd.startsWith("su -")) {
captureCmdOutput(in, channel);
}
channel.setInputStream(null);
channel.disconnect();
}
}
public static void captureCmdOutput(InputStream in, Channel channel) throws IOException {
System.out.println("Capturing cmdOutput now...");
byte[] tmp = new byte[1024];
while (true) {
System.out.println("in the while loop...");
while (in.available() > 0) {
System.out.println("into the available loop...");
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) {
System.out.println(ee.getMessage());
}
}
System.out.println("Command output captured...");
}
public static void open() throws JSchException {
JSch jSch = new JSch();
session = jSch.getSession(Constants.userId, Constants.host, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(Constants.userPasswd);
System.out.println("Connecting SSH to " + Constants.host + " - Please wait for few seconds... ");
session.connect();
System.out.println("Connected!\n");
}
public static void close() {
session.disconnect();
System.out.println("\nDisconnected channel and session");
}
}
pom.xml
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.51</version>
</dependency>
su命令用法:
su [options] [-] [USER [arg]...]
Change the effective user id and group id to that of USER.
A mere - implies -l. If USER not given, assume root.
Options:
-m, -p, --preserve-environment do not reset environment variables
-g, --group <group> specify the primary group
-G, --supp-group <group> specify a supplemental group
-, -l, --login make the shell a login shell
-c, --command <command> pass a single command to the shell with -c
--session-command <command> pass a single command to the shell with -c
and do not create a new session
-f, --fast pass -f to the shell (for csh or tcsh)
-s, --shell <shell> run shell if /etc/shells allows it
-h, --help display this help and exit
-V, --version output version information and exit
For more details see su(1).