-1

Using jsch i have login to the remote host execute the script as different user. Have to use "exec" channel. current unix action i do is: 1) sudo su - 2) run script

How can i run this command "sudo su - " and then execute the script in the same channel


Updated code comments and i am trying to send below two command as input. it is running in loop and i dont see it is getting executed. the below tw are the input sent in the array list "commands" sudo su - testusr /home/testusr/start.sh

ChannelShell channel = null;

List<String> result = new ArrayList<String>();
InputStream inStream = null;
OutputStream outStream = null;

PipedOutputStream pOutStream = null;
PipedInputStream pInStream = null;
try {
    inStream = new PipedInputStream();
    pOutStream = new PipedOutputStream((PipedInputStream) inStream);

    outStream = new PipedOutputStream();
    pInStream = new PipedInputStream((PipedOutputStream) outStream);
    channel = (ChannelShell) session.openChannel("shell");
    // channel.setPty(true);
    channel.setInputStream(inStream);
    channel.setOutputStream(outStream);
    channel.connect();
    BufferedReader bfs = null;

    for (String command : commands) {
        LOGGER.info("Executing command {} ", command);
        pOutStream.write((command.concat("\n")).getBytes());
    }
    LOGGER.info(" exit status {}", channel.getExitStatus());
    bfs = new BufferedReader(new InputStreamReader((inStream)));
    if (channel.getExitStatus() != 0) {

        result.add("ERROR");
    }
    String line;
    byte[] bt = new byte[1024];
    while (true) {
        while (inStream.available() > 0) {
            int i = inStream.read(bt, 0, 1024);
            if (i < 0) {
                break;
            }
            LOGGER.info("result {}", new String(bt, 0, i));
        }
        if (channel.isClosed()) {
            LOGGER.info("exit status {}", channel.getExitStatus());
            break;
        }
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2ned EDIT

for (String command : commands) {
                OutputStream out = channel.getOutputStream();
                out.write((command.concat("\n")).getBytes());
                out.flush();
                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;
                        }
                        LOGGER.info("Output stream execution {}", new String(
                                tmp, 0, i));
                    }
                    if (channel.isClosed()) {
                        LOGGER.info("Executing exit status {}",
                                channel.getExitStatus());
                        break;
                    }
                }
            }
Rajar R
  • 127
  • 1
  • 1
  • 10
  • as per this suggestion . ((ChannelExec)channel).setCommand("sudo -S -p '' "+command); how can i pass the run as user, in the session i will as login user , now i have switch sudo su - star – Rajar R Aug 28 '17 at 12:13
  • yes tried the same in putty terminal before execute using jsch as below, but it prompts for password in putty terminal,so the same behaviour will come using jsch . "sudo su -c /home/testusr/rn.sh - testusr – Rajar R Aug 28 '17 at 13:12
  • su - testusr. this prompts for password. these tries are from putty terminal , i have not tested using jsch. in putty terminal , if i do sudo su - testusr. it does not prompt for password – Rajar R Aug 28 '17 at 13:18
  • yes you are write. – Rajar R Aug 28 '17 at 14:04
  • 1
    OK, so use the second approach suggested in https://stackoverflow.com/a/41674203/850848 – Martin Prikryl Aug 28 '17 at 14:09
  • Since you suggested best approach is to use exec – Rajar R Aug 28 '17 at 15:48
  • added the code for the shell execution and getting infinite loop and the shell script also not invoked – Rajar R Aug 29 '17 at 13:18
  • i misunderstood as your comments mentions feed command to shell from the link. " feed the command to the shell using its standard input, i.e. the same way you provide the password: out.write(("command\n").getBytes());" – Rajar R Aug 29 '17 at 13:26
  • that works now. but input stream that reads goes in infinite loop, have updated the code above – Rajar R Aug 29 '17 at 14:02
  • Of course it does! What would make it break? See [JSch Shell channel execute commands one by one testing result before proceeding](https://stackoverflow.com/q/35533825/850848). – Martin Prikryl Aug 29 '17 at 14:11
  • In this case if i append the command the actual shell script is not invoked. "out.write(("sh /home/testur/run.sh".concat(" ; echo command-finished-return-code-$?")));" . Without this it goes in infinite loop. so the solution would be to add an echo statement at end of the shell script and check for the same in the loop rite? – Rajar R Aug 30 '17 at 12:28

1 Answers1

0

Do you really need to do sudo su -? If your script is a bash script, you may call sudo bash your_script.sh

This should work for any script type changing the interpreter.

The su - restores the user environment, if you really need it, your script may source ~/.bash_profile for example.

Xvolks
  • 2,065
  • 1
  • 21
  • 32