Uploaded image for project: 'CFEngine Community'
  1. CFEngine Community
  2. CFE-2724

commands: arglist is joined then split again



    • Type: Bug
    • Status: Open
    • Priority: Medium
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
    • Environment:
      CentOS 7.4 x86_64
      cfengine-community 3.10.x



      https://docs.cfengine.com/docs/3.10/reference-promise-types-commands.html#arglist is expected to be the proper solution to pass arguments with spaces inside them:

      That's particularly useful when there are embedded spaces and quotes in your arguments [...].

      But it does not seem to be handled differently than args and therefore does not work.

      Here's the example.cf showing the issue:

      body common control
            bundlesequence => { "example" };
      body contain pouet
        useshell   => "noshell";
      bundle agent example
               arglist => {"foo", "bar baz"},
               contain => pouet;

      pouet.sh is as follows:

      echo "number of args: $#"
      echo "first: $1"
      echo "second: $2"

      So in example.cf we passed two arguments to the script ("foo" and "bar baz"), but cfengine passed 3 of them:

      # cf-agent -KI ./example.cf 
          info: Executing 'no timeout' ... '/root/pouet.sh foo bar baz'
        notice: Q: "...t/pouet.sh foo ": number of args: 3
      Q: "...t/pouet.sh foo ": first: foo
      Q: "...t/pouet.sh foo ": second: bar
          info: Last 3 quoted lines were generated by promiser '/root/pouet.sh foo bar baz'
          info: Completed execution of '/root/pouet.sh foo bar baz'

      I expected this output:

       # /root/pouet.sh "foo" "bar baz"
       number of args: 2
       first: foo
       second: bar baz

      From a quick look at the C code, it seems that cfengine will join all arguments with spaces and then split them again, which defeats the purpose of arglist...


      For reference I wrote a simple c program using execv/execl to show what I expected when using argument lists:

      #include <stdio.h>
      #include <unistd.h>
      int main (int argc, char *argv[]) {
        if (argc != 2) {
          fprintf(stderr, "Usage: %s l|v\n", argv[0]);
          return 42;
        if (*argv[1] == 'l')
          execl("/root/pouet.sh", "pouet.sh", "foo", "bar baz", NULL);
          execv("/root/pouet.sh", (char *[]) { "pouet.sh", "foo", "bar baz", NULL });
        return 42;

      and the output when running it:

      # ./how-it-should-be l
      number of args: 2
      first: foo
      second: bar baz
      # ./how-it-should-be v
      number of args: 2
      first: foo
      second: bar baz


          Issue Links



              • Assignee:
                a10003 Eystein Maloy Stenberg
                mrpouit Lionel Le Folgoc
              • Votes:
                0 Vote for this issue
                1 Start watching this issue


                • Created:

                  Summary Panel