/* * LinuxScreenUtils.java * * Created on Aug 31, 2011, 10:58:34 AM * * Description: Provides utility methods to manage Linux Screen sessions. * * Copyright (C) Aug 31, 2011, Stephen L. Reed, Texai.org. * */ package org.texai.util; import java.io.IOException; import net.jcip.annotations.NotThreadSafe; import org.apache.log4j.Logger; /** Provides utility methods to manage Linux Screen sessions. * * @author reed */ @NotThreadSafe public class LinuxScreenUtils { /** the logger */ public static final Logger LOGGER = Logger.getLogger(LinuxScreenUtils.class); /** Prevents the construction a new LinuxScreenUtils instance. */ private LinuxScreenUtils() { } /** Launches a detached screen session with the given command. * * @param workingDirectory the working directory * @param command the given command * @param sessionName the name of the screen session */ public static void launchDetachedScreenSession( final String workingDirectory, final String command, final String sessionName) { //Preconditions assert workingDirectory != null : "workingDirectory must not be null"; assert !workingDirectory.isEmpty() : "workingDirectory must not be an empty string"; assert command != null : "command must not be null"; assert !command.isEmpty() : "command must not be empty"; assert sessionName != null : "sessionName must not be null"; assert !sessionName.isEmpty() : "sessionName must not be empty"; if (!EnvironmentUtils.isLinux()) { // do not try to create a screen session on Windows return; } String[] cmdArray = { "sh", "-c", "" }; final StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("cd "); stringBuilder.append(workingDirectory); stringBuilder.append(" ; screen -S "); stringBuilder.append(sessionName); // start a detached screen session with a forked process stringBuilder.append(" -L -h 5000 -d -m "); stringBuilder.append(command); cmdArray[2] = stringBuilder.toString(); LOGGER.info("shell cmd: " + cmdArray[2]); try { final Process process = Runtime.getRuntime().exec(cmdArray); final StreamConsumer errorConsumer = new StreamConsumer(process.getErrorStream(), LOGGER); final StreamConsumer outputConsumer = new StreamConsumer(process.getInputStream(), LOGGER); errorConsumer.setName("errorConsumer"); errorConsumer.start(); outputConsumer.setName("outputConsumer"); outputConsumer.start(); int exitVal = process.waitFor(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("exitVal: " + exitVal); } process.getInputStream().close(); process.getOutputStream().close(); } catch (InterruptedException ex) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("interrupted"); } } catch (final IOException ex) { throw new TexaiException(ex); } } /** Tests the screen launching method. * * @param args the command line arguments - unused */ public static void main(final String[] args) { LinuxScreenUtils.launchDetachedScreenSession( System.getProperty("user.dir"), // workingDirectory "ftp", // command "test-session"); // sessionName // reed@mccarthy:~/svn/Texai/Utilities$ screen -list // There is a screen on: // 22329.test-session (08/31/2011 11:51:39 AM) (Detached) // 1 Socket in /var/run/screen/S-reed. // // reed@mccarthy:~/svn/Texai/Utilities$ screen -R // ... exit the ftp application // [screen is terminating] // reed@mccarthy:~/svn/Texai/Utilities$ screen -ls // No Sockets found in /var/run/screen/S-reed. } }