CFEngine defines a number of variables for embedding unprintable values or values with special meanings in strings.

code
bundle agent __main__
{
  vars:
      "example_file"
        string => "/tmp/const-vars.txt";

  files:
      "$(example_file)"
        create => "true",
        content => concat("CFEngine const vars$(const.n)",
                          "before const.at $(const.at) after const.at$(const.n)",
                          "before const.dollar $(const.dollar) after const.dollar$(const.n)",
                          "before const.dirsep $(const.dirsep) after const.dirsep$(const.n)",
                          "before const.linesep $(const.linesep) after const.linesep$(const.n)",
                          "before const.endl$(const.endl) after const.endl$(const.n)",
                          "before const.n$(const.n) after const.n$(const.n)",
                          "before const.r $(const.r) after const.r$(const.n)",
                          "before const.t $(const.t) after const.t$(const.n)");

  reports:
      "const vars available: $(with)"
        with => storejson( variablesmatching_as_data( "default:const\..*" ) );

      "$(example_file):"
        printfile => cat( "$(example_file)" );
}
body printfile cat(file)
{
        file_to_print => "$(file)";
        number_of_lines => "inf";
}
code
R: const vars available: {
      "default:const.at": "@",
      "default:const.dirsep": "/",
      "default:const.dollar": "$",
      "default:const.endl": "\n",
      "default:const.linesep": "\n",
      "default:const.n": "\n",
      "default:const.r": "\r",
      "default:const.t": "\t"
}
R: /tmp/const-vars.txt:
R: CFEngine const vars
R: before const.at @ after const.at
R: before const.dollar $ after const.dollar
R: before const.dirsep / after const.dirsep
R: before const.linesep 
R:  after const.linesep
R: before const.endl
R:  after const.endl
R: before const.n
R:  after const.n
R: before const.r 

```cf3
 after const.r

R: before const.t after const.t ```

This policy can be found in /var/cfengine/share/doc/examples/const.cf and downloaded directly from github.

const.at

code
reports:

   "The value of $(const.at) is @";

History:

  • Added in CFEngine 3.19.0, 3.18.1

const.dollar

code
reports:

   # This will report: The value of $(const.dollar) is $
   "The value of $(const.dollar)(const.dollar) is $(const.dollar)";

   # This will report: But the value of $(dollar) is $(dollar)
   "But the value of $(dollar) is $(dollar)";

const.dirsep

code
reports:

   # On Unix hosts this will report: The value of $(const.dirsep) is /
   # On Windows hosts this will report: The value of $(const.dirsep) is \\
   "The value of $(const.dollar)(const.dirsep) is $(const.dirsep)";

const.linesep

code
reports:

   # On Unix hosts this will report: The value of $(const.linesep) is \n
   # On Windows hosts this will report: The value of $(const.linesep) is \r\n
   "The value of $(const.dollar)(const.linesep) is $(const.linesep)";

History: Introduced in CFEngine 3.23.0

const.endl

code
reports:

  "A newline with either $(const.n) or with $(const.endl) is ok";
  "But a string with \n in it does not have a newline!";

Note: The variable const.endl is an alias for const.n and nothing more. It is commonly mistaken to be a platform agnostic line separator. But this has never been the case. However, since CFEngine 3.23 we introduced const.linesep which is exactly that.

const.n

code
reports:

  "A newline with either $(const.n) or with $(const.endl) is ok";
  "But a string with \n in it does not have a newline!";

const.r

code
reports:

  "A carriage return character is $(const.r)";

const.t

code
reports:

  "A report with a$(const.t)tab in it";