0

I wrote the following ExecShellResult fragment in cfengine v2.2.1a:

control:
    active_interface_mac = ( ExecShellResult(/sbin/ifconfig ${active_interface} | /usr/bin/grep 'ether ' | /usr/bin/cut -f2 -d' ') )
    ...
    time_drift = ( ExecShellResult(/usr/sbin/ntpdate -d pool.ntp.org 2>/dev/null | /usr/bin/grep -o 'offset.*sec' | /usr/bin/cut -f2 -d' ') )
    ...
shellcommands:
    "/bin/echo ${time_drift}" inform=true syslog=true

When running the above from the command line, it obviously works fine:

$ ntpdate ...
0.183693

However, if run inside cfengine, I get a syntax error:

$ cfagent -qIK
Executing script /bin/echo /usr/bin/cut...(timeout=0,uid=-1,gid=-1)
cfengine:/bin/echo /usr/: /usr/bin/cut
cfengine: Finished script /bin/echo /usr/bin/cut
cfengine: 
Executing script /bin/echo  option requires an argument -- d usage...(timeout=0,uid=-1,gid=-1)
cfengine:/bin/echo  opti: option requires an argument -- d usage
cfengine: Finished script /bin/echo  option requires an argument -- d usage
cfengine: 
Executing script /bin/echo  cut -b list [-n] [file ...]        cut -c list [file ...]        cut -f list [-s] [-d delim] [file ...]...(timeout=0,uid=-1,gid=-1)
cfengine:/bin/echo  cut : cut -b list [-n] [file ...] cut -c list [file ...] cut -f list [-s] [-d delim] [file ...]
cfengine: Finished script /bin/echo  cut -b list [-n] [file ...]        cut -c list [file ...]        cut -f list [-s] [-d delim] [file ...]

Note the error is being displayed when we run the echo command under shellcommands:. By then, the ${time_drift} variable has been already evaluated, and its result shows we invoke cut's -d option incorrectly, complaining that we didn't pass anything to -d which is obviously not true.

This is baffling, because ${active_interface_mac} uses the same syntax and works perfectly.

I tried replacing the second grep with | tail -1 | sed 's///', another grep -o [0-9]*.[0-9] or anything else I could think of, including /usr/bin/cut -f1 -d'${spc}'. I apparently can't use awk because cfengine interprets $(NF) as parentheses which are part of ExecShellResult, even when escaped.

What other options do I have to get my actual seconds value extracted from ntpdate's output?

Virgil Gheorghiu
  • 493
  • 1
  • 4
  • 13

1 Answers1

0

I'm unsure about cfengine 2, I don't see what would trip it up in your example but for cfengine 3:

bundle agent main
{
  vars:

    "ntpdate_s"
      string => execresult( "/usr/sbin/ntpdate -d pool.ntp.org 2> /dev/null | /usr/bin/awk '/offset .* sec/ {print $10}'", useshell ),
      if => not( isvariable( offset ) );

  reports:
    "Mac address of wlan0 $(sys.hardware_mac[wlan0])";
    "Offset is $(ntpdate_s)";
}

Output:

R: Mac address of wlan0 5c:e0:c5:9f:f3:8f
R: Offset is 0.027672
Nick Anderson
  • 316
  • 1
  • 4