92

在 bash 中在后台运行进程相当容易。

$ echo "Hello I'm a background task" &
[1] 2076
Hello I'm a background task
[1]+  Done                    echo "Hello I'm a background task"

但是输出很冗长。第一行打印后台任务的作业 ID 和进程 ID,然后是命令的输出,最后是作业 ID、状态和触发作业的命令。

有没有办法抑制运行后台任务的输出,使输出看起来与最后没有 & 符号的输出完全相同?IE:

$ echo "Hello I'm a background task" &
Hello I'm a background task

我问的原因是我想将后台进程作为选项卡完成命令的一部分运行,因此该命令的输出必须不间断才能有意义。

4

8 回答 8

109

与完成无关,但您可以通过将调用放在子shell中来抑制该输出:

(echo "Hello I'm a background task" &)
于 2011-10-07T13:08:58.287 回答
14

基于@shellter的回答,这对我有用:

tyler@Tyler-Linux:~$ { echo "Hello I'm a background task" & disown; } 2>/dev/null; sleep .1;
Hello I'm a background task
tyler@Tyler-Linux:~$

我不知道这背后的原因,但我记得有一篇旧帖子不承认会阻止 bash 输出进程 ID。

于 2014-04-14T01:33:38.873 回答
12

在一些较新版本的 bash 和 ksh93 中,您可以用子 shell 或进程组(即{ ... })包围它。

/home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null
Hello I'm a background task
/home/shellter $
于 2011-10-07T13:08:34.660 回答
7

基于这个答案,我想出了更简洁和正确的:

silent_background() {
    { 2>&3 "$@"& } 3>&2 2>/dev/null
    disown &>/dev/null  # Prevent whine if job has already completed
}
silent_background date
于 2018-06-27T10:58:05.113 回答
6

Building on the above answer, if you need to allow stderr to come through from the command:

f() { echo "Hello I'm a background task" >&2; }
{ f 2>&3 &} 3>&2 2>/dev/null
于 2014-12-07T05:56:34.867 回答
5

尝试:

user@host:~$ read < <( echo "Hello I'm a background task" & echo $! )
user@host:~$ echo $REPLY
28677

你已经隐藏了outputPID。请注意,您仍然可以从 $REPLY检索PID

于 2016-06-13T00:38:28.453 回答
4

很抱歉对旧帖子的回复,但我认为这对其他人有用,这是谷歌的第一个回复。

我在使用这种方法(子shell)并使用“等待”时遇到问题。但是,当我在函数中运行它时,我能够做到这一点:

function a {
    echo "I'm background task $1"
    sleep 5
}

function b {
    for i in {1..10}; do
        a $i &
    done
    wait
} 2>/dev/null

当我运行它时:

$ b
I'm background task 1
I'm background task 3
I'm background task 2
I'm background task 4
I'm background task 6
I'm background task 7
I'm background task 5
I'm background task 9
I'm background task 8
I'm background task 10

在我收到提示之前有 5 秒的延迟。

于 2017-03-21T09:53:50.363 回答
1

subshel​​l 解决方案有效,但我也希望能够等待后台作业(并且最后没有“完成”消息)。$!在当前交互式 shell 中,来自子 shell 的不是“可等待的”。唯一对我有用的解决方案是使用我自己的等待功能,这非常简单:

myWait() {
  while true; do
    sleep 1; STOP=1
    for p in $*; do
      ps -p $p >/dev/null && STOP=0 && break
    done
    ((STOP==1)) && return 0
  done
}

i=0
((i++)); p[$i]=$(do_whatever1 & echo $!)
((i++)); p[$i]=$(do_whatever2 & echo $!)
..
myWait ${p[*]}

很容易。

于 2017-09-26T17:12:16.873 回答