我可以在 bash 中“导出”函数吗?

我可以在 bash 中“导出”函数吗?
source some_file

一些_文件:

doit ()
{
  echo doit $1
}
export TEST=true

如果我来源一些文件函数“doit”和变量 TEST 可在命令行上使用。但是运行这个脚本:

脚本.sh:

#/bin/sh
echo $TEST
doit test2

将返回 TEST 的值,但会生成有关未知函数“doit”的错误。

我也可以“导出”该函数,还是必须在 script.sh 中获取 some_file 才能在那里使用该函数?

答案1

在 Bash 中,您可以将函数定义导出到脚本调用的其他 shell 脚本中

export -f function_name

例如,您可以尝试这个简单的示例:

./script1:

#!/bin/bash

myfun() {
    echo "Hello!"
}

export -f myfun
./script2

./script2:

#!/bin/bash

myfun

然后如果你打电话./script1你会看到输出你好!

答案2

使用“导出”函数export -f会创建带有函数体的环境变量。考虑这个例子:

$ fn(){ echo \'\"\ \ \$; }
$ export -f fn
$ sh -c printenv\ fn
() {  echo \'\"\ \ \$
}

这意味着只有 shell(只是 Bash?)才能接受该函数。您还可以自己设置该函数,因为 Bash 只考虑以() {as 函数开头的 envvar:

$ fn2='() { echo Hi;}' sh -c fn2
Hi
$ fn3='() {' sh -c :
sh: fn3: line 1: syntax error: unexpected end of file
sh: error importing function definition for `fn3'

如果您需要通过 SSH“导出”此变量,那么您确实需要该函数作为字符串。这可以通过内置-p函数 ( ) 的打印选项 ( -f)来完成:declare

$ declare -pf fn
fn () 
{ 
    echo \'\"\ \ \$
}

如果您有需要通过 SSH 执行的更复杂的代码,这非常有用。考虑以下虚构脚本:

#!/bin/bash
remote_main() {
   local dest="$HOME/destination"

   tar xzv -C "$dest"
   chgrp -R www-data "$dest"
   # Ensure that newly written files have the 'www-data' group too
   find "$dest" -type d -exec chmod g+s {} \;
}
tar cz files/ | ssh user@host "$(declare -pf remote_main); remote_main"

答案3

建立在@Lekensteyn 的回答...

如果使用declare -pf它,会将当前 shell 中所有先前定义的函数输出到 STDOUT。

此时,您可以将 STDOUT 重定向到您想要的任何位置,并且实际上将之前定义的函数填充到您想要的任何位置。

下面的答案会将它们填充到一个变量中。然后,我们回显该变量以及我们想要运行到作为新用户生成的新 shell 中的函数的调用。我们通过使用(又名。 )sudo开关并简单地运行 Bash(它将接收管道 STDOUT 作为要运行的输入)来完成此操作。-uuser

正如我们所知,我们将从 Bash shell 转到 Bash shell,我们知道 Bash 将正确解释以前的 shell 定义的函数。只要我们在同一版本的一个 Bash shell 之间移动到同一版本的新 Bash shell,语法就应该没问题。

YMMV 如果您在不同的 shell 之间或在可能具有不同版本的 Bash 的系统之间移动。

#!/bin/bash
foo() {
  echo "hello from `whoami`"
}

FUNCTIONS=`declare -pf`; echo "$FUNCTIONS ; foo" | sudo -u otheruser bash
# $./test.sh
# hello from otheruser

答案4

eval "$(declare -F | sed -e 's/-f /-fx /')"将出口全部功能。

在启动脚本中的交互式 shell 之前,我经常这样做,以便我能够在使用其函数和变量的同时在脚本上下文中进行调试和工作。

例子:

eval "$(declare -F | sed -e 's/-f /-fx /')"
export SOME IMPORTANT VARIABLES AND PASSWORDS
bash -i

相关内容