Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events

Execution of shell script in AEM

Avatar

Level 2

Hi All,

I have requirement to get the AEM user input from form and send it to shell script and execute it and respond back to the user.

Shell script located in another location instead of aem server.

Does anyone worked on the same requirements.

I have tried process builder

But not able to access shell and execute it in AEM.

String command="/bin/bash"+""+param1;

Process process=new processbuilder(command)

Above code is working fine in Java .

Anything help would be appreciated.

Thanks 

 

 

 

5 Replies

Avatar

Community Advisor

Hi

 

I'm not entirely sure if I correctly understand your question, but if you're attempting to capture user input for executing a shell script, please be aware that it could pose a high-security risk. I strongly advise double-checking this aspect.

If your goal is to execute a shell script residing on a different server, there are a couple of alternatives. Let me highlight some:

 

  1. Utilize the JSch Library(http://www.jcraft.com/jsch/) to connect to the remote server and execute the script remotely. This library establishes an SSH connection between your server and the remote one via Java. Once the connection is established, you can execute the script as needed. Here is a snippet that could be of interest:
import com.jcraft.jsch.*;

public class RemoteScriptExecutor {

    public static void main(String[] args) {
        String host = "your_remote_host";
        String username = "your_username";
        String password = "your_password";
        String scriptPath = "/path/to/your/script.sh";

        executeRemoteScript(host, username, password, scriptPath);
    }

    public static void executeRemoteScript(String host, String username, String password, String scriptPath) {
        try {
            JSch jsch = new JSch();
            Session session = jsch.getSession(username, host, 22);
            session.setPassword(password);

            // Disable strict host key checking
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);

            // Connect to the remote server
            session.connect();

            // Execute the remote script
            Channel channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand("bash " + scriptPath);

            // Set up input and output streams if needed
            // InputStream in = channel.getInputStream();
            // OutputStream out = channel.getOutputStream();

            // Connect and wait for the command to complete
            channel.connect();
            channel.disconnect();

            // Disconnect from the remote server
            session.disconnect();

            System.out.println("Remote script executed successfully.");
        } catch (JSchException e) {
            e.printStackTrace();
        }
    }
}

2) Establish an HTTP client on the remote server capable of receiving HTTP requests and triggering the execution of the shell script. For instance, you may deploy a lightweight and efficient node server, creating an endpoint dedicated to script execution. Alternatively, consider incorporating Tomcat, XAMPP, or LAMP, depending on your server environment. Since the service endpoint handles script execution on the remote server, you encounter no additional complications. 

 

3) Building upon the previously mentioned concept, you can incorporate a serverless function, such as an AWS Lambda, to invoke the script from the server. This approach allows you to circumvent the need for installing a web server on the remote server.

 

 

Hope this helps:

Some references:
http://www.jcraft.com/jsch/ 

https://stackabuse.com/executing-shell-commands-with-node-js/

https://medium.com/stackfame/how-to-run-shell-script-file-or-command-using-nodejs-b9f2455cb6b7

https://www.tecracer.com/blog/2023/05/run-shell-scripts-as-lambda.html

https://medium.com/@the.nick.miller/use-python-lambdas-to-remotely-run-shell-commands-on-ec2-instanc... 



Esteban Bustamante

Avatar

Level 2

Hi @EstebanBustamante ,

I already gone through above URL.

Let me rephrase my question again.

I have created one form which accept 3paramter after click on submit , I called slingservlet to pass those parameters .

In slingservelt I am trying to access the shell script and passing same 3parameter and execute in the same sling servlet.

Here shell script reside in the same server where aem setup reside.

Hope now it is clear my requirement.

Thanks

Avatar

Community Advisor

@bangar20 then you just need to make sure your shell script accepts 3 parameters and then you could execute the shell script from the sling servlet (OSGI service preferable). You can use ProcessBuilder API for this scenario, you could try something like the below:

import java.io.IOException;

public class MyServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        try {
            // Specify the command with parameters
            String command = "/path/to/your/script.sh";
            // TODO: Get the parameters from your form
            String parameter1 = "value1";
            String parameter2 = "value2";
            String parameter3 = "value3";

            // Create a process builder with parameters
            ProcessBuilder processBuilder = new ProcessBuilder(command, parameter1, parameter2, parameter3);

            // Redirect error stream to output stream
            processBuilder.redirectErrorStream(true);

            // Start the process
            Process process = processBuilder.start();

            // Read the output of the process
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                out.println(line);
            }

            // Wait for the process to finish
            int exitCode = process.waitFor();

            // Print the exit code
            log.debug("Script executed with exit code: " + exitCode);
        } catch (Exception e) {
            log.error(e+ "The script terminated with error: " + out);
        } finally {
            out.close();
        }
    }
}

 

Make sure the script has the correct rights to be executed by AEM process.

 

Check this article explaining ProcessBuilder API:

 https://www.baeldung.com/java-lang-processbuilder-api 

https://mkyong.com/java/java-processbuilder-examples/ 

 

Regards



Esteban Bustamante

Avatar

Administrator

@bangar20 Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni