I am using file in which I passed below commands:
hostname
pwd
pbrun su - fclaim
whoami
cd ..
pwd
Ad the Java code below:
for (String command1 : commands) {
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command1);
in=channel.getInputStream();
channel.connect();
byte[] tmp=new byte[1024];
while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)
break;
System.out.println(new String(tmp, 0, i));
}
if(channel.isClosed()){
break;
}
}
channel.setInputStream(null);
channel.disconnect();
}
But I'm getting this output:
- some hostname
/home/imam
- missing output
imam
- missing output
/home/imam
Your code executes each command in an isolated environment. So your second whoami
does not run within pbrun su
, as you probably hoped for.
The pbrun su
executes a new shell.
To provide a command to the shell you either:
specify the command on su
command-line, like the official JSch Sudo.java
example shows:
((ChannelExec)channel).setCommand("pbrun su - fclaim -c whoami");
or feed the command to the shell using its standard input:
OutputStream out = channel.getOutputStream();
out.write(("whoami\n").getBytes());
See also:
Executing multiple bash commands using a Java JSch program after sudo login and
Running command after sudo login.
In general, I recommend the first approach as it uses a better defined API (command-line argument).
I had a similar issue and got it resolved with some help from @Martin
, lot of R&D and scanning through SO links. Here is the program that worked for me.
public class SSHConn {
static Session session;
static String suCmds = "su - simba -c \"whoami ; pwd\"";
static String[] commands = {"whoami", suCmds};
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("\nExecuting 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...");
}
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) {
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) {
System.out.println(ee.getMessage());
}
}
}
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");
}
}
Output:
Connecting SSH to my-unix-box.net - Please wait for few seconds...
Connected!
Executing command: whoami
Capturing cmdOutput now...
john
Executing command: su - simba -c "whoami ; pwd"
Setting suPasswd now....
Flushed suPasswd to cli...
Capturing cmdOutput now...
simba
/home/simba
Disconnected channel and session