将功能传递给Bash中的另一个用户?


11

有什么方法可以将功能从一个用户传递给另一个用户?

例如,我有一个小的Bash脚本,可以作为Root执行:

#!/bin/bash
user_func(){
  whoami
  exit
}
su vagrant -c 'user_func'

但是,user_func函数不是为Vagrant用户定义的,仅针对Root的,并且无法执行。

我的另一种选择是有多行

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

或者,执行多个命令,例如:su vagrant -c 'cmd1; cmd2; cmd3;',但是我不希望多余,尤其是当尝试以Vagrant用户身份执行5条以上的命令时。

是否可以从同一脚本中将功能传递给另一个用户(例如,不以其他用户的身份在磁盘上创建脚本,然后执行该生成的脚本)?还是我还有其他选择?

Answers:


10

听起来您首先需要export该功能定义:

#!/bin/bash
user_func (){
  whoami
  exit
}
export -f user_func
su vagrant -c 'user_func'

应该可以。

-f告诉export这是一个函数名称而不是变量名称。引用自help export

标记每个NAME以自动导出到随后执行的命令的环境。....

选项:

 -f   refer to shell functions

正如peterph和Stephane在评论中所指出的,这假定了两件事:

  1. 您的su命令不会覆盖用户的环境
  2. vagrant是登录shell bash。如果没有,您可以使用suStephane提供的备用命令行:

    su vagrant -c 'bash -c user_func'

这正是我所希望的。我没有意识到您将能够导出该功能。就像我希望在编辑示例脚本之后那样,它可以正常工作。谢谢!
gdieckmann

1
很好,但是在su覆盖环境的情况下不起作用。
彼得

1
请注意,它只能如果登录shell vagrantbash。如果没有,su vagrant -c 'bash -c user_func'
斯特凡Chazelas

6

有点黑,但是您可以在传递给的sommand中打印函数的定义,su然后当然可以使用它。

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

即使由于某种原因su而覆盖的外壳环境将被覆盖,这也将起作用,因为它将定义放在外壳初始化之后。如果您足够兼容地编写该函数,则当有问题的两个用户使用不同的Shell时,它甚至可以工作。


+1真正整洁的把戏!只是一个问题,su外壳环境是否会被外部因素覆盖?我的意思是,在这种情况下,su由于它在脚本中,因此您可以完全控制命令行。它的新外壳环境如何被覆盖?
Joseph R.

例如,由生成的shell su可能会对环境进行了一些初始化。同样,su它本身可能会剥夺呼叫者的某些环境,以稍微加强安全性(尽管通常是通过功能更强大的替代方法,例如sudo)来完成的。
peterph 2013年

0

那不是您拥有的脚本,而是一个函数。听起来好像您想要一个脚本。根据需要,编写一个合适的脚本,然后放在/usr/local/bin或中/home/vagrant/bin,然后应该可以例如su vagrant -c '/home/vagrant/bin/myscript.sh'


它是示例脚本中的函数。我希望将我想做的所有事情都包含在单个脚本中(命令以Root和Vagrant用户身份运行),而不必为Root用户有一个单独的脚本,为Vagrant用户有一个单独的脚本。
gdieckmann

0

另一种更可移植的方式(没有bash依赖性)是让脚本调用自身,并根据上下文(uid)或参数来更改其行为。文档中给出了这些示例,这些示例super显示了需要root权限的脚本,如果不是root用户,则通过super调用其self。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.