ExecuteCommandLine in OH3 not working

OK, new test. The file is been created. But the text isn’t added.
So it looks liks >, >> or | is giving some issues…

rule "1. Test"
when
        Item TestKnop1 changed
then
        logInfo("TEST", "...Test start...")
        executeCommandLine("touch", "/tmp/test")
        executeCommandLine("echo", "TEST", ">", "/tmp/test")
        logInfo("TEST", "...Test end ...")
end

File that’s been created:

-rw-r--r-- 1 openhab openhab 0 Jan  8 11:12 /tmp/test

I’ve also tried to changed that file rights, but no luck, nothing is been added…

I do not have much experience in java code.
The source code of executecommandLine to me looks like redirecting STDOUT and STDERR is inhibited:

    public static void executeCommandLine(String... commandLine) {
        try {
            new ProcessBuilder(commandLine).redirectError(Redirect.DISCARD).redirectOutput(Redirect.DISCARD).start();
        } catch (IOException e) {
            logger.warn("Error occurred when executing commandLine '{}'", commandLine, e);
        }
    }
1 Like

I also have issues like @brononius above and I suspect the \n to cause the issue - but it’s just a guess.

I would like to execute this:

executeCommandLine(Duration.ofSeconds(10),  "/bin/ls", "/var/www/upload/abus", "-1tr", "|", "head", "-n", "-3000", "|", "xargs", "-d", "'\n'", "/bin/rm", "-f", "--")

it works flawlessly in bash using:

/bin/ls /var/www/upload/abus -1tr | head -n -3000 | xargs -d '\n' /bin/rm -f --

any idea what might be wrong?

I tried it with ‘\\n’ already

With executeCommandLine you can only start one program with arguments.
Starting multiple programs (with redirection and pipes) is a function of a command shell.

So you must put your

/bin/ls /var/www/upload/abus -1tr | head -n -3000 | xargs -d '\n' /bin/rm -f --

line in a sh file and execute this.

Also only a guess from side, maybe you should try quoting the \n with a backslash
So it should look like this in the rule:

executeCommandLine(Duration.ofSeconds(10), “/bin/ls”, “/var/www/upload/abus”, “-1tr”, “|”, “head”, “-n”, “-3000”, “|”, “xargs”, “-d”, “\\n’”, “/bin/rm”, “-f”, “–”)

or you “simply” create a shell skript with the complete command inside. chmod, that the user openhab can execute the script. After that just call the script in the rule (only a example):

executeCommandLine(Duration.ofSeconds(10), “/app/scripts/skript.sh”)

Guys, you are quick!

I tried this already - does not work
(unfortunately the code above swallowed the second )

Alright - thank you.
I thought I could avoid shell scripts, but there is potentially no other way!

I’m struggling with this too. The problem is that the script I want to execute takes a variable number of arguments that are determined at runtime, so splitting them up like executeCommandLine("python", "/home/openhab/myscript.py", arg1, arg2, ...) is not an option. Replacing spaces with @ or @@ as often recommended doesn’t work either. Spaces were not a problem back in OH2’s executeCommandLine().

Why does this issue even exist? What is the purpose of splitting up arguments? Please just let me pass a string directly to bash or whatever like any other exec function out there does. That would also solve all problems that users have with piping etc at once.

Aren’t you missing the time out at the beginning?

executeCommandLine(Duration.ofSeconds(5), "python", "/home/openhab/myscript.py", "arg1", "arg2", "...")

Furthermore you need " around the args as well.

Encapsulate your call to python in a shell scirpt ( as long as you do not have dynamic arguments ).
Replacing spaces with @s does not work in OH3 afaik.

The timeout is optional. It’s just a little confusing (for me at least) because it comes first, and optional stuff usually comes at the tail end.

EDIT: Oops, we both missed this post from earlier in the conversation. So it’s required if you need a response, and not required if you don’t.

1 Like

That’s only required if you want to process the output.

I meant those to be variables. But this style of passing arguments isn’t useful for me anyway because I have a string with an arbitrary number of spaces.

That’s the problem.

That’s because of how Java’s Varargs work. If a method accepts an arbitrary number of arguments, they always need to be at the very end.

However, that’s also the solution! I just found out it’s possible to pass an array instead of individual arguments:

val cmnd = "python /home/openhab/myscript.py " + myarguments
executeCommandLine(cmnd.split(" "))

You can’t mix both however, so executeCommandLine("python", "/home/openhab/myscript.py", myarguments.split(" ")) will not work.

4 Likes