有没有办法使bash作业控制安静?

时间:2012-06-19 09:03:35

标签: bash shell unix parallel-processing

在后台运行作业时,Bash非常冗长:

$ echo toto&
toto
[1] 15922
[1]+  Done                    echo toto

因为我试图并行运行作业并使用输出,所以我想找到一种方法来沉默bash。有没有办法删除这个多余的输出?

5 个答案:

答案 0 :(得分:37)

您可以使用括号在子shell中运行后台命令,这将使作业控制消息静音。例如:

(sleep 10 & )

答案 1 :(得分:25)

注意:以下内容适用于交互式 Bash会话。在脚本中,作业控制消息从不打印。

沉默Bash的作业控制消息 2基本情景

启动和忘记:

CodeGnome's helpful answer answer建议将后台命令括在一个简单的子shell中 - 例如,(sleep 10 &) - 这有效地使作业控制消息无效 - 在作业创建和工作终止

这有重要的副作用

  • 通过在子shell中使用控件操作符& 失去对后台作业的控制 - jobs不会列出它,也不会%%(最近启动的作业的规范(ID))和$!(启动(最后)进程的PID(作为一部分)最近的工作)将反映出来。 [1]

对于启动并忘记的情况,这是一个问题

  • 你刚开始后台工作,
  • 并且你让它自己完成(并且你相信它能正确运行)。

[1]可以想象,您可以通过搜索与其命令行匹配的流程来自行查找流程,但这样做很麻烦且不易于实现。

启动并控制后:

如果您想保持对作业的控制,以便以后可以:

  • 杀死,如果需要的话。
  • 同步等待(在稍后的某个时间点)完成,

需要采用不同的方法:

  • 在下面处理创建作业控制消息的静音,但为了静默终止作业控制消息分类< / em> ,您必须关闭作业控制shell选项

    • set +mset -m重新开启)
    • 警告:这是全局设置,其中包含许多重要副作用,特别是:
      • 后台命令的Stdin是/dev/null而不是当前的shell。
      • 禁用暂停( Ctrl-Z )和延迟暂停( Ctrl-Y )前景命令的键盘快捷键。
      • 有关完整报道,请参阅man bash和(不区分大小写)搜索&#34;作业控制&#34;
      • 的出现次数。
  • 静音创建作业控制消息,请将后台命令包含在组命令中并重定向后者&#39 ; s stderr输出到/dev/null

    { sleep 5 & } 2>/dev/null
    

以下示例说明如何在原则上保留对作业的控制的同时静静地启动后台作业。

$ set +m; { sleep 5 & } 2>/dev/null # turn job-control option off and launch quietly
$ jobs # shows the job just launched; it will complete quietly due to set +m 

如果您想要关闭作业控制选项(set +m),那么使终止作业静音的唯一方法是 - 控制消息是kill作业或wait

警告:有两个边缘情况,此技术仍会产生输出:

  • 如果后台命令尝试立即从stdin 读取
  • 如果后台命令立即终止

安静地启动工作(如上所述,但没有set +m):

$ { sleep 5 & } 2>/dev/null

悄悄地wait:{/ p>

$ wait %% 2>/dev/null    # use of %% is optional here

悄悄地kill

{ kill %% && wait; } 2>/dev/null

需要额外的wait才能使终止作业控制消息通常由Bash 异步显示(在实际进程终止时,在kill之后不久)a <来自wait的em>同步输出,然后允许静音。

但是,如上所述,如果作业单独完成 ,则仍会显示作业控制消息。

答案 2 :(得分:1)

用虚拟脚本包裹它:

quiet.sh:

#!/bin/bash
$@ &

然后调用它,将命令作为参数传递给它:

./quiet.sh echo toto

根据您的输入,您可能需要使用引号。

答案 3 :(得分:1)

互动,不。它将始终显示作业状态。您可以使用set -b来影响状态显示。

没有什么可以阻止你使用命令的输出(通过管道,或存储变量等)。作业状态由shell发送到控制终端,不与其他I / O混合。如果你正在做一些复杂的工作,解决方案是编写一个单独的脚本。

如果你的bashrc中有一些函数可以直接访问你的交互式环境,那么作业消息只会是一个问题。不幸的是,你无能为力。

答案 4 :(得分:-2)

一个解决方案(无论如何都是bash)是将所有输出路由到/ dev / null

    echo 'hello world' > /dev/null &

除了bg进程的id之外,上面的代码不会给你任何输出。