001/* 002 * (C) Copyright 2006-2015 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 * tdelprat, jcarsique 017 * 018 */ 019 020package org.nuxeo.ecm.platform.commandline.executor.service.executors; 021 022import java.io.File; 023import java.io.IOException; 024import java.util.ArrayList; 025import java.util.Collections; 026import java.util.List; 027 028import org.apache.commons.lang.ArrayUtils; 029import org.apache.commons.lang.StringUtils; 030import org.apache.commons.lang3.SystemUtils; 031import org.apache.commons.logging.Log; 032import org.apache.commons.logging.LogFactory; 033import org.apache.commons.logging.impl.SimpleLog; 034 035import org.nuxeo.ecm.platform.commandline.executor.api.CmdParameters; 036import org.nuxeo.ecm.platform.commandline.executor.api.ExecResult; 037import org.nuxeo.ecm.platform.commandline.executor.service.CommandLineDescriptor; 038import org.nuxeo.ecm.platform.commandline.executor.service.EnvironmentDescriptor; 039import org.nuxeo.log4j.ThreadedStreamGobbler; 040 041/** 042 * Default implementation of the {@link Executor} interface. Use simple shell exec. 043 * 044 * @author tiry 045 */ 046public class ShellExecutor extends AbstractExecutor { 047 048 private static final Log log = LogFactory.getLog(ShellExecutor.class); 049 050 @Deprecated 051 @Override 052 public ExecResult exec(CommandLineDescriptor cmdDesc, CmdParameters params) { 053 return exec(cmdDesc, params, new EnvironmentDescriptor()); 054 } 055 056 @Override 057 public ExecResult exec(CommandLineDescriptor cmdDesc, CmdParameters params, EnvironmentDescriptor env) { 058 long t0 = System.currentTimeMillis(); 059 List<String> output = Collections.synchronizedList(new ArrayList<String>()); 060 061 String[] cmd; 062 try { 063 if (SystemUtils.IS_OS_WINDOWS) { 064 String[] paramsArray = getParametersArray(cmdDesc, params); 065 cmd = new String[] { "cmd", "/C", cmdDesc.getCommand() }; 066 cmd = (String[]) ArrayUtils.addAll(cmd, paramsArray); 067 } else { 068 String paramsString = getParametersString(cmdDesc, params); 069 cmd = new String[] { "/bin/sh", "-c", cmdDesc.getCommand() + " " + paramsString }; 070 } 071 } catch (IllegalArgumentException e) { 072 return new ExecResult(cmdDesc.getCommand(), e); 073 } 074 String commandLine = StringUtils.join(cmd, " "); 075 076 Process p1; 077 try { 078 if (log.isDebugEnabled()) { 079 log.debug("Running system command: " + commandLine); 080 } 081 ProcessBuilder processBuilder = new ProcessBuilder(cmd).directory(new File(env.getWorkingDirectory())); 082 processBuilder.environment().putAll(env.getParameters()); 083 p1 = processBuilder.start(); 084 } catch (IOException e) { 085 return new ExecResult(commandLine, e); 086 } 087 088 ThreadedStreamGobbler out, err; 089 if (cmdDesc.getReadOutput()) { 090 out = new ThreadedStreamGobbler(p1.getInputStream(), output); 091 err = new ThreadedStreamGobbler(p1.getErrorStream(), output); 092 } else { 093 out = new ThreadedStreamGobbler(p1.getInputStream(), SimpleLog.LOG_LEVEL_DEBUG); 094 err = new ThreadedStreamGobbler(p1.getErrorStream(), SimpleLog.LOG_LEVEL_ERROR); 095 } 096 097 err.start(); 098 out.start(); 099 100 int exitCode = 0; 101 try { 102 exitCode = p1.waitFor(); 103 out.join(); 104 err.join(); 105 } catch (InterruptedException e) { 106 return new ExecResult(commandLine, e); 107 } 108 109 long t1 = System.currentTimeMillis(); 110 return new ExecResult(commandLine, output, t1 - t0, exitCode); 111 } 112}