Несколько команд, использующих JSch
Мое требование заключается в следующем:
Я должен войти в систему Unix, используя мои учетные данные, и после входа в систему я должен сделать sudo другому пользователю. Как только sudo будет успешным, я должен вызвать shell в nohup. По завершении выполнения закройте канал и сессию.
Я попробовал первый шаг, который связан с использованием команды sudo, но я не знаю, как вызвать сценарий оболочки после команды sudo.
В приведенном ниже коде я могу выполнить команду sudo, но после получения доступа sudo, как я могу выполнить оболочку в nohup с пользователем masteruser
, Так что для создания необходимых файлов моя оболочка имеет владельца как masteruser
,
public class SSHUploader {
Session session = null;
public SSHUploader(){
}
public void connect(){
try {
JSch jsch = new JSch();
session = jsch.getSession("user", "xxx.xxx.xx.xx", 22);
session.setPassword("test");
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void executeCommand(String script) throws JSchException, IOException{
System.out.println("Execute sudo");
String sudo_pass = "test";
ChannelExec channel = (ChannelExec) session.openChannel("exec");
((ChannelExec) channel).setCommand( script);
InputStream in = channel.getInputStream();
OutputStream out = channel.getOutputStream();
((ChannelExec) channel).setErrStream(System.err);
channel.connect();
out.write((sudo_pass + "\n").getBytes());
out.flush();
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()) {
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
System.out.println(ee);
}
}
channel.disconnect();
System.out.println("Sudo disconnect");
}
public void disconnect(){
session.disconnect();
}
public static void main(String... args) throws JSchException, IOException {
SSHUploader up = new SSHUploader();
up.connect();
up.executeCommand("sudo -u masteruser bash");
up.disconnect();
}
}
3 ответа
Для последовательного выполнения нескольких команд вы можете создать командную строку, как показано ниже:
String script ="pbrun su - user; cd /home/scripts;./sample_script.sh”
Выполните его и передайте эту строку вашему методу выше.
Сообщение может быть старым, но я нашел другой простой способ, который позволяет вам получать выходные данные каждой команды в отдельности. Обратите внимание, что этот код должен быть выполнен после открытия сеанса, как показано в примерах ( http://www.jcraft.com/jsch/examples/Exec.java.html):
for (String command : commands) {
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setInputStream(null);
channel.setErrStream(System.err);
channel.setCommand(command);
channel.connect();
printOutput(channel);
channel.disconnect();
}
куда printOutput
использования channel.getInpuStream()
прочитать результат команды.
Еще одно решение, которое я считаю элегантным, - использовать соединение из типаshell
вместоexec
. Но вам нужно будет дождаться появления правильного приглашения после каждой команды, как показано в следующем примере:
public static void main(String[] args) throws Exception{
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
Session session = null;
ChannelShell channel = null;
try {
JSch jsch = new JSch();
session = jsch.getSession("username", "192.168.1.1", 22);
session.setConfig(config);
session.setPassword("password");
session.connect();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
channel = (ChannelShell) session.openChannel("shell");
channel.setOutputStream(outputStream);
PrintStream stream = new PrintStream(channel.getOutputStream());
channel.connect();
stream.println("touch delme.txt");
stream.flush();
String response = waitForPrompt(outputStream, "$");
System.out.println(response);
stream.println("sudo chown root delme.txt");
stream.flush();
response = waitForPrompt(outputStream, ":");
System.out.println(response);
stream.println("mysecretrootpassword");
stream.flush();
response = waitForPrompt(outputStream, "$");
System.out.println(response);
stream.println("ls -la delme.txt");
stream.flush();
response = waitForPrompt(outputStream, "$");
System.out.println(response);
} finally {
if (channel != null) {
channel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
static public String waitForPrompt(ByteArrayOutputStream outputStream, String prompt) throws Exception {
int retries = NUMBER_OF_RETRIES;
for (int x = 1; x < retries; x++) {
TimeUnit.SECONDS.sleep(1);
if (outputStream.toString().indexOf(prompt) > 0) {
String responseString = outputStream.toString();
outputStream.reset();
return responseString;
}
}
throw new Exception("Prompt failed to show after specified timeout");
}