在后台使用符号(&;)运行子进程时,运行bash脚本不会返回到终端

在后台使用符号(&;)运行子进程时,运行bash脚本不会返回到终端,bash,shell,scripting,background-process,ampersand,Bash,Shell,Scripting,Background Process,Ampersand,我有一个脚本(我们称之为parent.sh),它对运行java进程的第二个脚本(child.sh)进行两次调用。child.sh脚本通过在parent.sh中的行末尾放置&在后台运行。但是,当我运行parent.sh时,我需要按Ctrl+C返回到终端屏幕。这是什么原因?是否与child.sh进程在parent.sh进程下运行有关。所以parent.sh直到孩子们死了才死 parent.sh #!/bin/bash child.sh param1a param2a & child.sh p

我有一个脚本(我们称之为parent.sh),它对运行java进程的第二个脚本(child.sh)进行两次调用。child.sh脚本通过在parent.sh中的行末尾放置&在后台运行。但是,当我运行parent.sh时,我需要按Ctrl+C返回到终端屏幕。这是什么原因?是否与child.sh进程在parent.sh进程下运行有关。所以parent.sh直到孩子们死了才死

parent.sh

#!/bin/bash
child.sh param1a param2a &
child.sh param1b param2b &
exit 0
child.sh

#!/bin/bash
java com.test.Main 
echo "Main Process Stopped" | mail -s "WARNING-Main Process is down." user@email.com    

如您所见,我不想在后台运行java进程,因为我想在进程结束时发送邮件。从功能的角度来看,按照上面的方法操作很好,但是我想知道如何在执行parent.sh之后让它返回到终端。

下面的链接建议在
child.sh中的
mail
命令之后添加
wait

上述文件摘要 在脚本中,在后台使用符号(&)运行命令 可能会导致脚本挂起,直到按ENTER键。这似乎发生在 写入标准输出的命令。这可能是一个很大的烦恼

..

正如Walter Brameld IV所解释的:

据我所知,这样的脚本实际上并没有挂起。只是 似乎是因为后台命令将文本写入 提示后将显示控制台。用户得到的印象是 提示从未显示。以下是事件的顺序:

  • 脚本启动后台命令
  • 脚本退出
  • Shell将显示提示
  • 后台命令继续运行并将文本写入 控制台
  • 后台命令完成
  • 脚本认为,用户在输出的底部看不到提示 他被吊死了
  • 如果将
    child.sh
    更改为如下所示,则不应体验到这种烦恼:

    #!/bin/bash
    java com.test.Main
    echo "Main Process Stopped" | mail -s "WARNING-Main Process is down." user@gmail.com
    wait
    
    或者正如@SebastianStigler在对您上述问题的评论中所述:


    在邮件行的末尾添加一个
    /dev/null
    。否则,mail将尝试启动其交互模式

    这将导致mail命令写入
    /dev/null
    ,而不是
    stdout
    ,这也将停止这种麻烦


    希望这对我有所帮助,我最后做的是将parent.sh更改为以下内容

    #!/bin/bash
    child.sh param1a param2a > startup.log &
    child.sh param1b param2b > startup2.log &
    exit 0
    
    如果没有您的建议和对问题的根本原因分析,我不会得出这个解决方案。谢谢


    并为我不准确的评论道歉。(没有输入,我从内存中回答,但我记错了。)

    进程仍然链接到控制终端,因为STDOUT
    需要去某个地方。您通过重定向到一个文件(
    >startup.log
    )解决了这个问题

    如果您对输出不感兴趣,请完全放弃标准输出(
    /dev/null

    如果您对错误也不感兴趣,则丢弃这两个(
    &>/dev/null

    如果您希望进程在注销终端后仍能继续运行,请使用nohup——这样可以有效地将进程与您正在执行的操作断开连接,并让进程在后台安静运行,直到您重新启动计算机(或以其他方式杀死它们)


    它需要是ctrl-c还是按enter键也会得到提示?
    ps
    说在点击ctrl-c时运行的是什么?java程序是否需要任何输入?如果您将其更改为
    java com.test.Main
    ,是否有帮助?请在带有
    mail
    的行末尾添加一个
    /dev/null
    <代码>邮件
    将尝试启动其交互模式。@theGuardian,如果它接受输入,您希望它如何为自己设置背景?它必须有一个控制终端句柄。正如@CharlesDuffy所说,如果脚本接受输入,它如何在后台运行?它将从哪里获得输入?你没有提供它(而且你用ctrl-c杀死它,我希望你实际上必须打它两次)。我也遇到了同样的问题,这对我很有效。如果不需要收集输出,则将
    &
    替换为
    /dev/null&
    也有效。OP还可以在最后一次调用
    child.sh
    之后(就在
    退出0
    之前)添加
    wait
    命令,效果相同。
    nohup child.sh param1a param2a &>/dev/null &