How can I execute a command that uses command substitution in CFEngine?

Posted by Nick Anderson
May 13, 2019

This was originally published here, it has been re-published with permission.

How can I execute a command that uses command substitution in CFEngine?

On the console I might execute something like this:

Listing 1: Example command substitution

touch /tmp/file-$(date --iso-8601)
ls /tmp/file-*
/tmp/file-2019-03-08

I recommend not executing commands using substitution. Instead, prepare all that you need up front. Get the result of the data command and put it into a CFEngine variable, then use the CFEngine variable directly.

bundle agent main
{
  vars:
      "date" string => execresult( "date --iso-8601=second", useshell );
      "command" string => "/usr/bin/touch /tmp/file-$(date)";
      "result" string => execresult( $(command), useshell );

  reports:
      "CFEngine $(sys.cf_version)";
      "Executed $(command)" if => isvariable( result );
      "Files:$(const.n)$(with)" with => join( "$(const.n)", lsdir( "/tmp/", "file-.*", false ));
}
R: CFEngine 3.13.0
R: Executed /usr/bin/touch /tmp/file-2019-03-08T11:34:37-06:00
R: Files:
file-2019-03-08T11:34:21-06:00
file-2019-03-08T11:34:34-06:00
file-2019-03-08T11:34:37-06:00
file-2019-03-08T11:34:24-06:00

But, if you really want to use command substitution you can use backticks directly.

bundle agent main
{
  vars:
      "command" string => "/usr/bin/touch /tmp/file2-`date --iso-8601=second`";
      "result" string => execresult( $(command), useshell );

  reports:
      "CFEngine $(sys.cf_version)";
      "Executed $(command)" if => isvariable( result );
      "Files:$(const.n)$(with)" with => join( "$(const.n)", lsdir( "/tmp/", "file2-.*", false ));
}
R: CFEngine 3.13.0
R: Executed /usr/bin/touch /tmp/file2-`date --iso-8601=second`
R: Files:
file2-2019-03-08T11:36:30-06:00
file2-2019-03-08T11:36:35-06:00

Why is it so?

CFEngine expands variables wrapped in $() and ${} and functions are skipped (e.g. execresult()) if they have parameters that are variables that do not dereference.

Get in touch with us
to discuss how we can help!
Contact us
Sign up for
our newsletter
By signing up, you agree to your email address being stored and used to receive newsletters about CFEngine. We use tracking in our newsletter emails to improve our marketing content.