Run puppet exec command only if output file has changed

Solution 1:

It would work like this:

exec { 'my_command.sh':
  command   => '/bin/my_command.sh',
  subscribe => [ 
    File['/etc/mysoftware/config.xml'], 
    File['/etc/othersoftware/defaults'], 
  ],
  refreshonly => true,
}

The obvious constraint here is, that the files /etc/mysoftware/config.xml and /etc/othersoftware/defaults must be changed via Puppet too.
If they are changed by something else (external to Puppet), see Felix' answer.
You can also subscribe to Package['xxx'] or any other more fitting dependency of course.

Solution 2:

Puppet can solve this through its audit metaparameter.

file { [ "/etc/mysoftware/config.xml", 
         "/etc/othersoftware/defaults" ]:
    audit => 'content',
    notify => Exec['my_command'],
}