【问题标题】:Call a function using nohup使用 nohup 调用函数
【发布时间】:2013-05-08 08:07:41
【问题描述】:

我正在尝试像这样使用nohup 调用函数:

function1(){
    while true 
    do
        echo "function1"
        sleep 1
    done
}

nohup function1 & 
# ...... some other code

但可能是nohup 看不到该功能,我收到此错误:

nohup: failed to run command `function1' : No such file or dictionary

我不想为我的函数创建新的 sh 文件。我该如何解决这个问题?

【问题讨论】:

  • nohup 需要文件(错误消息清楚地说明)作为参数,而不是函数。但是你可以做的是:修改上面的脚本,让它接受一个新的参数(例如“--nohup”),当这个参数被传递时,只需调用function1并在你的脚本中用nohup $0 --nohup &替换nohup function1 &
  • 你的意思是我必须在函数中使用nohup?我对调用函数的--nohup 选项感到困惑!

标签: linux bash function shell nohup


【解决方案1】:

另一种解决方案:

function background {
    echo TEST
}
export -f background 

nohup bash -c background &

【讨论】:

  • 如果你传入参数,不要忘记函数调用的引号:nohup bash -c 'background "hello there"' & 如果你的函数是echo "$1"
  • export: -f: unknown option
【解决方案2】:

nohup 适用于命令而非脚本函数。

例如,包含 function1() 的脚本(比如 func.sh)应该调用函数-:

function1(){
    while true 
    do
        echo "function1"
        sleep 1
    done

}

function1

现在用nohup在后台调用脚本func.sh-:

nohup ./func.sh &

如果您需要在脚本中禁用挂断信号,请使用 shell 内置 trap。该示例忽略 SIGHUP,但可用于忽略其他(例如 SIGINT)。

trap "" HUP   # script will ignore HANGUP signal

【讨论】:

  • 有没有在函数上应用 nohup ?我不喜欢使用几个 sh 文件。
  • 很遗憾没有。您可以做的是将常用功能保留在一个脚本中,然后获取它;这将减少脚本数量。
  • 有可用于捕获信号的陷阱命令 - 请参阅我编辑的答案。这可能符合您的要求。
【解决方案3】:

我找到了一个可行的解决方案 - 在文件中定义函数(例如 .functions),然后使用 nohup 运行函数:

nohup bash -c "source .functions; function1" &

在 Ubuntu 13.04 上测试。

【讨论】:

  • nohup bash -c 'source .functions"arg1"' & --> bash: .functions: No such file or directory 即使函数被定义为同一个 shell 脚本中的函数
【解决方案4】:

由于nohup 必须提供文件名而不是函数作为解决方法,因此可以这样做:

function1(){
    while true 
    do
        echo "function1"
        sleep 1
    done

}

echo "$@" | grep -q -- "--nohup" && function1 || nohup $0 "$@" --nohup & 

因此,当使用当前参数调用此脚本时:

  • `echo "$@" | grep -q -- "--nohup" 将返回错误状态,所以
  • nohup $0 "$@" --nohup & 将被调用,它将调用此脚本并传递当前参数和新参数 --nohup

当这个脚本用参数--nohup调用时

  • `echo "$@" | grep -q -- "--nohup" 将返回零状态(成功)所以
  • function1 将被调用

【讨论】:

    【解决方案5】:

    您可以像这样实现相同的结果,而不是使用为文件量身定制的 nohup:

    (trap '' HUP INT
     while true
     do
       echo "function1"
       sleep 1
     done
    ) </dev/null 2>&1 1>nohup.out &
    

    由于我倾向于从父脚本启动这些进程,并且如果父进程中断,父脚本可能会执行其他工作,我希望子进程忽略 INT 信号并继续运行。

    【讨论】:

    • 我不知道这个技巧。你能解释一下这是如何工作的吗?
    • 基本上trap 会捕获 SIGHUP 和 SIGINT 信号并忽略它们,从而允许我们创建一个独立的子 shell 来运行我们的函数。更详细的解释在这里:gist.github.com/bluekezza/e511f3f4429939a0f9ecb6447099b3dc
    【解决方案6】:

    是的!这是可能的,但是很棘手,并且严格 bash > v2 兼容:

    function1(){ local msg=${*:-function1}; echo msg=$msg; }
    nohup -- sh -c "$(typeset -f function1); function1 MESSAGE" >nohup.log 2>&1 0</dev/null &
    

    而且不要忘记“排版”已被 bash 弃用,取而代之的是“声明”(尽管我并不完全同意这一点)。

    【讨论】:

      猜你喜欢
      • 2022-10-20
      • 1970-01-01
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 2010-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多