Hi Linda Le,
please note the difference between server and client side actions.
- JavaScript is a client activity
- Velocity template is typically a server side activity.
If you want to run a shell script on the server you need a tool
in the velocity context, example - something in the Servlet
along the line:
context.put("Script", new ScriptTool())
This shows use of a Tool I wrote years ago and sent as a possible
contribution to the Velocity team. You will find the original
code in the attachment. You might also check for newer tools
like http://jakarta.apache.org/commons/sandbox/exec
NOTE: you need to take extreme care what is passed to the
invocation to not open any security holes. There are many
articles for Perl and PHP on what to avoid, similar precautions
are needed for Velocity using a shell tool.
Also look at the ToolboxManager of the VelocityTools project
http://velocity.apache.org/tools/devel/index.html
The attched ScriptTool is used in a Velovity template like:
#set( $control = $Script.exec('/bin/ftp -n localhost << \\') )
#call( $control.sendCommand("user $username $password") )
#call( $control.sendCommand("\\") )
#call( $control.waitForCompletion() )
#set( $status = $control.getStatus() )
#set( $stderr = $control.getStderr(false) )
#set( $stdout = $control.getStdout(false) )
A bit simpler is the $Script.call method, that returns the status
and stdout/stderr in a Hashtable. But the above Velocity-snippet
shows that you could remote-control your script and even let it
execute it in the background...
Cheers,
Christoph
Linda Le wrote:
> Hi
>
> Is it possible call perl or unix shell scripts from withing a Velocity
> template? The documentation shows lots of Java script. They use perl/unix
> scrpts in their environment. I was wondering if anyone on the list may have
> some examples we can have.
>
> Thanks.
>
>
> If you don't go after what you want, you'll never have it.
> If you don't ask, the answer is always no.
> If you don't step forward, you're always in the same place.
> (Nora Roberts)
>
>
/*
* $Header: $
* $Revision: 1.0 $
* $Date: 2001/06/13 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.tools;
import java.io.File;
import java.io.InputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;
import java.util.Hashtable;
import java.util.StringTokenizer;
/**
* Provides utilities to run scripts, feed the input and to buffer the
* output.
*
* @company Deutsches Zentrum fuer Luft- und Raumfahrt
* @author [EMAIL PROTECTED]
*/
public class ScriptTool
{
public static final int IDLE = -1000;
public static final int RUNNING = -1001;
public static final int START_FAILED = -1002;
/**
* Empty constructor.
*/
public ScriptTool()
{
}
/**
* Excecute a command and retrun a control handle to it..
*
* @param command The command and commandLine parameters to call.
* @return A ProcessControl handle.
*/
public ProcessControl exec(String command)
{
return new ProcessControl(command);
}
/**
* Calls a script defined in the command line.
*
* @param command The command and commandLine parameters to call.
* @return A hashtable{STATUS=Integer, STDOUT=String, STDERR=String].
*/
public Hashtable call(String command)
{
Hashtable callResult = new Hashtable(3, 1);
callResult.put("STATUS", new Integer(-1));
callResult.put("STDOUT", "");
callResult.put("STDERR", "ERROR");
ProcessControl control = exec(command);
control.waitForCompletion();
// get the exit value
int status = control.getStatus();
// construct result container
callResult.put("STATUS", new Integer(status));
callResult.put("STDOUT", control.getStdout(true));
if (status == START_FAILED)
callResult.put("STDERR", "ERROR: failed starting script");
else
callResult.put("STDERR", control.getStderr(true));
return callResult;
}
/**
* Inner class for continually pumping the input stream during
* Process's runtime.
**/
class StreamReader extends Thread
{
private InputStream inputStream;
private StringBuffer buf = new StringBuffer();
public StreamReader(InputStream inputStream, String name)
{
super(name);
this.inputStream = inputStream;
}
public String getOutput(boolean flush)
{
synchronized(buf)
{
String str = buf.toString();
if (flush)
buf.setLength(0);
return str;
}
}
public void run()
{
try
{
int count;
byte[] b = new byte[512];
while ( (count = inputStream.read(b)) > 0 ) // blocking read
{
synchronized(buf)
{
buf.append( new String(b, 0, count) );
}
}
inputStream.close();
}
catch (IOException ex) // must be caught
{
// ignore, since this will be flagged bu the executing process
}
}
}
/**
* Inner class for continually pumping the input stream during
* Process's runtime.
**/
public class ProcessControl
{
static final String shell = "csh -fe";
Process process;
StreamReader out;
StreamReader err;
DataOutputStream cmd;
int status = ScriptTool.IDLE;
protected ProcessControl(String command)
{
try
{
// start the process
process = Runtime.getRuntime().exec(shell);
cmd = new DataOutputStream( process.getOutputStream() );
cmd.writeChars(command + "\n");
// read stdout and stderr in separate threads
out = new StreamReader(process.getInputStream(), "exec");
err = new StreamReader(process.getErrorStream(), "error");
// starts background reading the generated output/error
out.start();
err.start();
// send the command to the shell
cmd.flush();
}
catch (IOException ioe) // must be caught
{
status = ScriptTool.START_FAILED;
}
}
public void terminate()
{
if (process != null)
{
// close the stdin
try
{
cmd.close();
}
catch (IOException ignore)
{
// ignore
}
process.destroy();
status = process.exitValue();
// wait for out/err threads to stop
while ( out.isAlive() )
{
try
{
out.join();
}
catch (InterruptedException ex)
{
// ignore
}
}
while ( err.isAlive() )
{
try
{
err.join();
}
catch (InterruptedException ex)
{
// ignore
}
}
// realease it
process = null;
}
}
public boolean isRunning()
{
if ( (process != null) && !out.isAlive() ) // do cleanup
terminate();
return (process != null);
}
public boolean sendCommand(String command)
{
try
{
cmd.writeChars(command + "\n");
cmd.flush();
}
catch (IOException ex)
{
return false;
}
return true;
}
public String getStdout(boolean flush)
{
return out.getOutput(flush);
}
public String getStderr(boolean flush)
{
return err.getOutput(flush);
}
public int getStatus()
{
return isRunning() ? ScriptTool.RUNNING : status;
}
public void waitForCompletion()
{
// close the stdin to allow process to complete
try
{
cmd.close();
}
catch (IOException ignore)
{
// ignore
}
while ( isRunning() )
{
try
{
process.waitFor();
terminate(); // do cleanup
}
catch (InterruptedException ex)
{
// ignore and continue retrying
}
}
}
/**
* Ensure the process is stopped and the resources are freed
* when this process is not referenced anymore (and the GC runs).
*/
public void finalize() throws Throwable
{
if ( isRunning() )
terminate();
super.finalize();
}
} // end of ProcessControl
} // end of ScriptTool.java
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]