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

sta*_*tti 38 unix parallel-processing bash shell

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

$ echo toto&
toto
[1] 15922
[1]+  Done                    echo toto
Run Code Online (Sandbox Code Playgroud)

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

Tod*_*obs 44

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

(sleep 10 & )
Run Code Online (Sandbox Code Playgroud)

  • @Dave:谢谢你让我深入挖掘.让我总结一下:`(sleep 10&)`可以方便地使创建和终止消息静音,但是你无法控制后台作业.为了避免这种情况,使用`{sleep 10&} 2>/dev/null`来静音_creation_消息,并使用`wait`或`kill`类似地使_termination_消息静音(这可能不总是一个选项).或者,可以使用`set + m`来对终止消息进行分类静音,然而,这有很多可能不需要的副作用.我的回答(希望如此)有完整的故事. (5认同)
  • `()` 表示法产生一个子shell,然后分叉另一个`&`,这不是最佳的 (2认同)

mkl*_*nt0 30

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

2个基本场景沉默bash的作业控制信息:


启动并忘记:

CodeGnome的有用答案答案建议将后台命令在一个简单的子shell中 - 例如,(sleep 10 &)- 有效地使作业控制消息无效 - 无论是在创造就业机会还是在作业终止时.

这有一个重要的副作用:

  • 通过使用控制运营商& 内部子shell,你失去了后台作业的控制 - jobs就不一一列举了,既不%%(规范(ID)最近推出的职业.)也不是$!(启动了(最后一个)进程的PID(作为最近工作的一部分)将反映它.[1]

对于启动 - 忘记方案,这不是问题:

  • 你刚开始做后台工作,
  • 你让它自己完成(你相信它运行正常).

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


启动和控制后:

如果您想继续控制工作,以便以后可以:

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

需要一种不同的方法:

  • 沉默创造就业,控制消息是以下处理,但为了 沉默终止作业控制消息明确,必须打开作业控制shell选项OFF:

    • set +m(set -m重新打开)
    • 警告:这是一个具有许多重要副作用全局设置,特别是:
      • 然后用于后台命令的Stdin /dev/null而不是当前的shell.
      • 用于挂起(Ctrl-Z)和延迟挂起(Ctrl-Y)前台命令的键盘快捷键被禁用.
      • 有关完整的故事,请参阅man bash和(不区分大小写)搜索"作业控制"的出现.
  • 要使创建作业控制消息静音,请将后台命令包含在组命令中,并将后者的stderr输出重定向到/dev/null

    { sleep 5 & } 2>/dev/null
    
    Run Code Online (Sandbox Code Playgroud)

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

$ 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 
Run Code Online (Sandbox Code Playgroud)

如果你希望关闭作业控制选项(set +m),沉默的唯一途径终止作业控制消息是要么kill工作或wait为它:

警告:有两种边缘情况,这种技术仍然产生输出:

  • 如果背景命令试图从标准输入读取的时候了.
  • 如果背景命令终止的时候了.

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

$ { sleep 5 & } 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

wait为它悄然:

$ wait %% 2>/dev/null    # use of %% is optional here
Run Code Online (Sandbox Code Playgroud)

为了kill它静静:

{ kill %% && wait; } 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

附加wait是必要的,以使终止作业控制消息通常由Bash 异步显示(在实际进程终止时,在kill之后不久)同步输出wait,然后允许静默.

但是,如上所述,如果作业本身完成,则仍会显示作业控制消息.

  • 请注意,组命令技术还有一个额外的警告:命令本身的标准错误输出被抑制。 (2认同)