Bash在后台运行作业时非常冗长:
$ echo toto& toto [1] 15922 [1]+ Done echo toto
由于我试图并行运行作业并使用输出,所以我想找到一种方法来使bash静音。有没有办法消除这种多余的输出?
ni65a41a1#
您可以使用括号在子shell中运行后台命令,这将使作业控制消息静音。例如:
(sleep 10 & )
edqdpe6u2#
注意:以下内容适用于 * 交互式 * Bash会话。在 scripts 中,作业控制消息 * 从不 * 打印。
CodeGnome's helpful answer answer建议将后台命令封装在一个简单的子shell中-例如(sleep 10 &)--这可以有效地抑制作业控制消息--无论是作业 * 创建 * 还是作业 * 终止 *。这有一个重要的副作用:
(sleep 10 &)
*通过在子shell中使用控制操作符&,您 * 失去了对后台作业的控制-jobs不会列出它,%%(规范)也不会列出它。$!(作为最近启动的作业的一部分启动的(最后一个)进程的PID)也不会反映它。[1]
&
jobs
%%
$!
对于launch-and-forget场景,这 * 不是 * 问题:
[1]可以想象,您可以通过搜索正在运行的进程以查找与其命令行匹配的进程来自己查找该进程,但这很麻烦,而且不容易使其健壮。
如果您想保持对作业的控制,以便以后可以:
需要采取不同的办法:
set +m
set -m
/dev/null
man bash
{ 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作业:
kill
wait
警告:有 * 两种边缘情况 * 这种技术仍然产生输出:
要安静地启动作业(如上所述,但不使用set +m):
$ { sleep 5 & } 2>/dev/null
给wait静静地为它:
$ wait %% 2>/dev/null # use of %% is optional here
要kill它悄悄地:
{ kill %% && wait; } 2>/dev/null
额外的wait是必要的,以使终止作业控制消息,通常显示 * 异步 * 由Bash(在实际的进程终止时,杀死后不久)从wait的 * 同步 * 输出,然后允许沉默。但是,如前所述,如果作业自行完成 *,则仍将显示作业控制消息。
50few1ms3#
将其 Package 在一个虚拟脚本中:quiet.sh:
#!/bin/bash $@ &
然后调用它,将你的命令作为参数传递给它:
./quiet.sh echo toto
你可能需要根据你的输入来玩报价。
llmtgqce4#
互动,不。它将始终显示作业状态。您可以使用set -b影响状态显示的时间。没有什么可以阻止您使用命令的输出(通过管道或存储it变量等)。作业状态由shell发送到控制端,不与其他I/O混合。如果你正在做一些复杂的工作,解决方案是编写一个单独的脚本。只有在bashrc中有一些函数使用了作业控制,并且希望直接访问交互式环境时,作业消息才是真正的问题。不幸的是你对此无能为力。
set -b
ie3xauqp5#
imho,最简单的方法来实现这一点,我在很多场合使用如下:
exec {oldfd2}<&2 # copy/dup stderr exec 2<&- # tell stderr to zip it sleep 3 & sleep3bgpid=$! someotherbgcmd 2>&$oldfd2 & #route stderr of this job to orig stderr otherbgcmdpid=$! # restore things as they were... exec 2<&$oldfd2 # restore stderr exec {oldfd2}>&- # close dup'ed fd unset oldfd2 # keep env clean ... unset sleep3bgpid othercmdbgpid
使用set +/-m时要小心,我在会话中运行了许多没有tty的任务,请参阅echo $-,其中假设存在作业控制是不正确的。在正常的交互式会话中,这些标志是:然而,在远程无tty会话中,它们是hiBH……干杯在这里输入代码
ajsxfq5m6#
一种解决方案(在bash中)是将所有输出路由到/dev/null
echo 'hello world' > /dev/null &
上面的代码除了bg进程的id之外不会给予你任何输出。
6条答案
按热度按时间ni65a41a1#
您可以使用括号在子shell中运行后台命令,这将使作业控制消息静音。例如:
edqdpe6u2#
注意:以下内容适用于 * 交互式 * Bash会话。在 scripts 中,作业控制消息 * 从不 * 打印。
Launch-and-Forget:
CodeGnome's helpful answer answer建议将后台命令封装在一个简单的子shell中-例如
(sleep 10 &)
--这可以有效地抑制作业控制消息--无论是作业 * 创建 * 还是作业 * 终止 *。这有一个重要的副作用:
*通过在子shell中使用控制操作符
&
,您 * 失去了对后台作业的控制-jobs
不会列出它,%%
(规范)也不会列出它。$!
(作为最近启动的作业的一部分启动的(最后一个)进程的PID)也不会反映它。[1]对于launch-and-forget场景,这 * 不是 * 问题:
[1]可以想象,您可以通过搜索正在运行的进程以查找与其命令行匹配的进程来自己查找该进程,但这很麻烦,而且不容易使其健壮。
Launch-and-control-later:
如果您想保持对作业的控制,以便以后可以:
*同步等待(在稍后的某个时间点)完成,
需要采取不同的办法:
set +m
(set -m
将其重新打开)*注意事项:这是一个全局设置,有许多重要的副作用,特别是:
/dev/null
,而不是当前shell的。man bash
和(不区分大小写)搜索“作业控制”的出现。/dev/null
下面的示例说明如何在原则上保留对作业的控制的同时悄悄启动后台作业。
如果您不想关闭作业控制选项(
set +m
),则使 * 终止 * 作业控制消息静音的唯一方法是kill
作业或wait
作业:警告:有 * 两种边缘情况 * 这种技术仍然产生输出:
要安静地启动作业(如上所述,但不使用
set +m
):给
wait
静静地为它:要
kill
它悄悄地:额外的
wait
是必要的,以使终止作业控制消息,通常显示 * 异步 * 由Bash(在实际的进程终止时,杀死后不久)从wait
的 * 同步 * 输出,然后允许沉默。但是,如前所述,如果作业自行完成 *,则仍将显示作业控制消息。
50few1ms3#
将其 Package 在一个虚拟脚本中:
quiet.sh:
然后调用它,将你的命令作为参数传递给它:
你可能需要根据你的输入来玩报价。
llmtgqce4#
互动,不。它将始终显示作业状态。您可以使用
set -b
影响状态显示的时间。没有什么可以阻止您使用命令的输出(通过管道或存储it变量等)。作业状态由shell发送到控制端,不与其他I/O混合。如果你正在做一些复杂的工作,解决方案是编写一个单独的脚本。
只有在bashrc中有一些函数使用了作业控制,并且希望直接访问交互式环境时,作业消息才是真正的问题。不幸的是你对此无能为力。
ie3xauqp5#
imho,最简单的方法来实现这一点,我在很多场合使用如下:
使用set +/-m时要小心,我在会话中运行了许多没有tty的任务,请参阅echo $-,其中假设存在作业控制是不正确的。在正常的交互式会话中,这些标志是:然而,在远程无tty会话中,它们是hiBH……干杯在这里输入代码
ajsxfq5m6#
一种解决方案(在bash中)是将所有输出路由到/dev/null
上面的代码除了bg进程的id之外不会给予你任何输出。