Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a script that really only needs to be run one time on a server, i.e. at deployment time, but figured it would be best to have Puppet manage it. The script remaps several legacy user id's that conflict with local system users.

The way I check this is if the gopher user has the default uid of 13. If so, then I need to run my remapping script.

exec { "change_uid":
   command  => "/script/to/",
   provider => 'shell',
   path => [ "/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/local/bin", "/usr/local/sbin" ],
   onlyif   => "test `/usr/bin/id -u gopher` -eq 13; echo $?",

I've tried several different permutations of the above onlyif check, but the exec always gets fired on the agent.

When I run that command directly on the command line, it returns either 0 or 1. It could be related to the fact that bash returns 0 when true and 1 when false, but I think its more likely that I'm misunderstanding the way onlyif works.

How can I have this exec fire when the gopher's uid=13? I'm open to alternative ways to implement what I'm trying to accomplish here.


I dropped the echo part. The final working solution is:

exec { "change_uid":
   command  => "/script/to/",
   path     => [ "/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/local/bin", "/usr/local/sbin" ],
   onlyif   => "test `id -u gopher` -eq 13",

Making use of the ralsh commmand was helpful in testing, thanks @Daniel C. Sobral. I'm marking @Daniel's as the accepted answer since that was the main issue, besides my misunderstanding of a few concepts, plus he answered first. Thanks all.

share|improve this question
up vote 8 down vote accepted

Did you try removing the echo $? at the end?

That part will always make the whole thing return 0.

share|improve this answer
Yup, I tried it in puppet with/without. Without the echo it returns nothing when tried via cmd line, regardless of how it evaluates, so I thought it may be needed. – Banjer Jun 14 '12 at 13:45
the onlyif uses the return value of the command, not the output – Daniel Jun 14 '12 at 19:54
OK so when I try out test ... on my linux command line (bash) as I have it written in my question above, the "echo $?" spits out a return value (0 or 1). Without the echo portion, nothing is returned. Isn't "echo $?" supposed to give you the return value of a command? – Banjer Jun 14 '12 at 20:37
@Banjer echo $? prints the return value of a command, and returns 0. onlyif needs the return value, so if you add that echo, it will always receive 0. – Daniel C. Sobral Jun 14 '12 at 21:05

The parameter onlyif limits process execution to when the command pointed by onlyif returns success (0). For example:

dcs@shadowfax:~/tmp$ ls -l test
ls: cannot access test: No such file or directory
dcs@shadowfax:~/tmp$ ralsh exec "/bin/echo ok" onlyif="/usr/bin/test -f test"
exec { '/bin/echo ok':
  returns => ['0'],
dcs@shadowfax:~/tmp$ touch test
dcs@shadowfax:~/tmp$ ralsh exec "/bin/echo ok" onlyif="/usr/bin/test -f test"
notice: /Exec[/bin/echo ok]/returns: executed successfully
exec { '/bin/echo ok':
  returns => 'notrun',

So, when the file does not exist, it doesn't do anything. When I create the file, it displays a notice to the effect that /bin/echo ok was executed.

Ignore that returns stuff.

Anyway, since you ended the onlyif command with an echo, and echo always return success, then your exec always get executed. Remove that echo and leave only the test command.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.