在 Bash 中将函数传递给另一个用户?

gdi*_*ann 10 bash

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

例如,我有一个以 Root 身份执行的小型 Bash 脚本:

#!/bin/bash
user_func(){
  whoami
  exit
}
su vagrant -c 'user_func'
Run Code Online (Sandbox Code Playgroud)

但是 user_func 函数没有为 Vagrant 用户定义,只为 Root 定义,不能执行。

我的另一个选择是多行

su vagrant -c 'cmd1' 
su vagrant -c 'cmd2'
, etc 
Run Code Online (Sandbox Code Playgroud)

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

是否可以从同一脚本中将函数传递给另一个用户(例如,不在磁盘上以不同用户的身份创建脚本,然后执行生成的脚本)?还是我忽略了另一种选择?

Jos*_* R. 10

听起来您首先需要export该函数定义:

#!/bin/bash
user_func (){
  whoami
  exit
}
export -f user_func
su vagrant -c 'user_func'
Run Code Online (Sandbox Code Playgroud)

应该做的伎俩。

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

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

选项:

 -f   refer to shell functions
Run Code Online (Sandbox Code Playgroud)

正如 peterph 和 Stephane 在评论中指出的那样,这假设有两件事:

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

    su vagrant -c 'bash -c user_func'
    
    Run Code Online (Sandbox Code Playgroud)


pet*_*rph 6

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

$ function foo { do_some_stuff_here; }
$ su test -c "$(typeset -f foo); foo"
Run Code Online (Sandbox Code Playgroud)

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