Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. 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

Is there any way that I can pass a Function from one user to another user?

For example, I have a small Bash script that I execute as Root:

su vagrant -c 'user_func'

However, the user_func Function isn't defined for the Vagrant user, only for Root, and can't be executed.

My other option would be to have multiple lines of

su vagrant -c 'cmd1' 
su vagrant -c 'cmd2'
, etc 

Or, execute multiple commands ex: su vagrant -c 'cmd1; cmd2; cmd3;', but I'd prefer to not have the excess, especially when attempting to execute more than 5 commands as the Vagrant user.

Is it possible to pass a Function to another user from within the same script (ex. not creating a script on disk as a different user and then executing that generated script)? Or is there another option that I am overlooking?

share|improve this question
up vote 8 down vote accepted

Sounds like you need to export that function definition first:

user_func (){
export -f user_func
su vagrant -c 'user_func'

should do the trick.

The -f tells export that this is a function name rather than a variable name. Quoting from help export:

Marks each NAME for automatic export to the environment of subsequently executed commands. ....


 -f   refer to shell functions

As pointed out by peterph and Stephane in the comments, this assumes two things:

  1. That your su command will not overwrite the user's environment
  2. That vagrant's login shell is bash. If not, you can use the alternative su command line provided by Stephane:

    su vagrant -c 'bash -c user_func'
share|improve this answer
This is actually exactly what I was hoping for. I didn't realize that you would be able to export the function. This worked just as I was hoping it would after editing the sample script. Thanks! – gdieckmann Dec 23 '13 at 21:48
Nice, but won't work in cases where su overrides the environment. – peterph Dec 23 '13 at 21:51
Note that it only works if the login shell of vagrant is bash. If not, su vagrant -c 'bash -c user_func' – Stéphane Chazelas Dec 23 '13 at 21:58

It's a bit hackish, but you can print the definition of the function inside the sommand passed to su and then you can of course use it.

$ function foo { do_some_stuff_here; }
$ su test -c "$(typeset -f foo); foo"

This will work even if for some reason the environment of the shell spawned by su will be overwritten, since it puts the definition after shell initialization. If you write the function compatibly enough, it will even work when the two users in question are using different shells.

share|improve this answer
+1 Really neat trick! Just a question though, can the su shell's environment be overwritten by external factors? I mean, in this case you have complete control over the su command line since it's in a script. How can its new shell's environment be overwritten? – Joseph R. Dec 23 '13 at 21:48
For example the shell spawned by su might do some initialization of environment. Also su itself might strip some of the caller's environment to tighten security a bit (although this is usually done by more powerful alternatives like sudo). – peterph Dec 23 '13 at 22:04
I see. Thanks for the info. – Joseph R. Dec 23 '13 at 22:05

That's not a script you have, it's a function. It sounds like you want a script, though. Make a proper script and put it, as your needs require, either in /usr/local/bin, or in /home/vagrant/bin, and than you should be able to e. g. su vagrant -c '/home/vagrant/bin/myscript.sh'

share|improve this answer
It's a function within a sample script. My hope was to include everything that I want to do within this single script (commands run as Root, and as the Vagrant user), and not have to have a separate script for the Root user and a separate script for the Vagrant user. – gdieckmann Dec 23 '13 at 21:37

Another somewhat more portable way to do this (no bash dependency) Is to have your script call its self and have its behavior change based on either context (uid) or parameters. examples of this are given in the documentation for super where they show a script that needs root permissions, calling its self through super when not root.

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.