Ask Your Question

How to execute "source" command?

asked 2013-07-21 22:03:46 -0600

99thPuppetUser gravatar image

updated 2013-07-21 23:11:24 -0600

ramindk gravatar image


How do I execute "source /usr/local/rvm/scripts/rvm" command using exec type reference?

Regards, a Puppet user.

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted

answered 2013-07-21 23:10:13 -0600

ramindk gravatar image

updated 2015-11-22 17:10:42 -0600

This comes up quite a bit so I'm going to try to explain all the interesting parts in one go.

The Exec resource uses the Posix provider by default

Executes external binaries directly, without passing through a shell or performing any interpolation. This is a safer and more predictable way to execute most commands, but prevents the use of globbing and shell built-ins (including control logic like “for” and “if” statements).

The Exec resource uses /bin/sh when you specify shell

Passes the provided command through /bin/sh; only available on POSIX systems. This allows the use of shell globbing and built-ins, and does not require that the path to a command be fully-qualified. Although this can be more convenient than the posix provider, it also means that you need to be more careful with escaping.

The important parts to remember is that any Bashism or other non Posix functions are missing. Most users have seen exactly this problem when they try to run a script from crontab without specifying a shell or environment.

The Exec shell does not load PATH

You will need to specify paths for all commands in the script or set path. Many people set a default path for Exec resources in site.pp, but you set them per Exec as well.

Exec { path => '/usr/bin:/bin' }

How to use Exec with a particular shell, source files, have access to ENV, etc

Using RVM as an example your Exec resource might look like the following.

exec { 'passenger_install_gem':
  user      => $rvm::user,
  command   => "bash -c 'source ~/.rvm/scripts/rvm ; gem install passenger -v ${passenger::version}'",
  unless    => "bash -c 'source ~/.rvm/scripts/rvm ; gem list | grep passenger | grep ${passenger::version}'",
  logoutput => on_failure,
  path      => '/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin' } 

Notice that we've specified the user we plan to run as rather than letting it default to root. Then we spawn a Bash shell with -c, source the necessary environment files, and finally execute our command. I recommend setting logoutput => on_failure, when working with Exec resources.

edit flag offensive delete link more


Do we need to specify the entire path in the command, I thought there is a "cwd" attribute (in exec resource type)specifically for this purpose. I am curious I kindly request you to let me know.

R gravatar imageR ( 2015-05-08 14:40:20 -0600 )edit

// , Ramindk, did you mean to say, "The important parts to remember is that any Bashism or other non Posix functions will not work." in the third sentence, there?

NathanBasanese gravatar imageNathanBasanese ( 2015-09-04 18:39:03 -0600 )edit

I did, finally got around to fixing this. Thanks.

ramindk gravatar imageramindk ( 2015-11-22 17:11:07 -0600 )edit

answered 2014-03-28 16:45:35 -0600

DracoBlue gravatar image

You can avoid sourcing the rvm file, if you do bash --login -c 'your command'. This will behave like a normal bash (with sourcing .bash_rc [which includes the rvm] + setting up the PATH in a proper way).

This might be a better solution, because you don't have to take care of the PATH, too.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2013-07-21 22:03:46 -0600

Seen: 10,355 times

Last updated: Nov 22 '15