Execute Command Task

In Working with the Client API we briefly covered how to execute a command using the AbstractCommandTask. In the Maverick NG Client API tasks are how we perform operations over SSH. This article outlines the options available for the AbstractCommandTask.

When we talk about executing a command over SSH we are speaking specifically about executing a single command line in a single session. This is not the same as starting a shell and executing commands in an interpreter like bash. Executing a command is equivalent to the following ssh command line operation

    ssh lee@localhost ls -l

In this scenario the command is executed and the session remains open until the command completes. Once complete the session is closed and can no longer be used for any other command execution. If you need to execute a further command you need to open a new session. Therefore this method is not suitable for executing interactive commands and does not provide a shell. 

The template for using the command task is as follows: 

    con.addTask(new AbstractCommandTask(con, "ls -l") {
	protected void onOpenSession(SessionChannel session) {

        protected void onCloseSession(SessionChannel session) {

} });

The AbstractCommandTask has an InputStream implementation that will allow you to read from the command output. You should do this in the onOpenSession method of your implementation of AbstractCommandTask.

    protected void onOpenSession(SessionChannel session) {		
	try {
	    int b;
	    byte[] buf = new byte[1024];
	    while((b = getInputStream().read(buf)) > -1) {
	        // Use the buffer as needed
	} catch (IOException e) {
} }

Similarly if you need to write out to the command you can use getOutputStream method of AbstractCommandTask to write to the remote process.  


Allocating a Pseudo Terminal

In the case that the command being executed requires a pseudo terminal. You can request that one be allocated on the SshContext.



Getting the Exit Code

When an SSH session closes the server sends the process exit code to the client. You can check the exit code once the session has been fully closed. The best method to do this is to add the handling code to the onCloseSession method of your task implementation.

    protected void onCloseSession(SessionChannel session) {
	if(session.getExitCode()!=SessionChannel.EXITCODE_NOT_RECEIVED) {
	    log.info("Command completed with exit code " + session.getExitCode());

Please be aware that this is an optional operation for the server to implement. Therefore you cannot guarantee that an exit code will be received. 








Have more questions? Submit a request


Please sign in to leave a comment.