Search code examples
linuxbashvariablespuppetpuppet-enterprise

Can't set a bash variable using exec command in Puppet


I'm trying to set the result of a bash command in a variable using the exec command in Puppet :

 exec { 'test':
     command => "test=$(pwd)",
     path =>  [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ],
     logoutput => true,
}

But it's giving me a :

Error: Could not find command 'test=$(pwd)'

What could be the solution for this?


Solution

  • I'm trying to set the result of a bash command in a variable using the exec command in Puppet :

    exec { 'test':
         command => "test=$(pwd)",
         path =>  [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ],
         logoutput => true,
    }
    

    On Linux, the default provider for Exec resources is posix. If you want the command to be executed via a shell then you need to ask for that by adding

         provider => 'shell',
    

    But you cannot affect Puppet's execution environment from within such a shell, so any environment variables you set, shell options you modify, etc will be in effect only for the duration of that command. For example, you cannot that way set environment variables for a subsequent Exec to use.

    That is, this will work as expected:

    # Ok
    
    exec { 'test':
      command   => 'test=$(pwd); echo "${test}"',
      path      => ['/bin', '/sbin' , '/usr/bin', '/usr/sbin'],
      logoutput => true,
      provider  => 'shell',
    }
    

    , but this is unlikely to produce the same result:

    # Not what you want!
    
    exec { 'set test':
      command   => 'test=$(pwd)',
      path      => ['/bin', '/sbin' , '/usr/bin', '/usr/sbin'],
      logoutput => true,
      provider  => 'shell',
    }
    
    exec { 'print test':
      command   => 'echo "${test}"',
      path      => ['/bin', '/sbin' , '/usr/bin', '/usr/sbin'],
      logoutput => true,
      provider  => 'shell',
    }
    

    (Note also quoting. Puppet will expand ${test} where it appears in a double-quoted string, possibly to nothing. To avoid that, escape the $ as \$ or use single quotes instead of double quotes.)


    It's unclear what your overall objective is, because pwd is not a useful thing to be capturing in an Exec resource. If you care about the locations of files, then you should be referring to them via absolute paths, except inasmuch as you may use simple command names that can be resolved against the path you specify in your Exec.

    If you want to add variables to your commands' (quite sparse) environments then the environment parameter of the Exec resource is usually the most appropriate way to do it, but you cannot use command substitutions there. You can, however, interpolate the values of facts or ordinary Puppet variables, and that might be a good route to what you're after.

    If you want to execute a complex-ish series of related shell commands, then you could consider writing a shell script to a file on the target system, and executing that. Or look for an existing module that does what you want, or even write a custom resource type that uses Ruby (and maybe shell commands underneath) to do it.