在后台运行bash命令而不打印作业和进程ID

时间:2011-10-07 12:06:26

标签: bash bash-completion

在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,它的状态和触发作业的命令。

有没有办法抑制运行后台任务的输出,使输出看起来与没有前后的&符号完全一样?即:

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

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

8 个答案:

答案 0 :(得分:68)

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

(echo "Hello I'm a background task" &)

答案 1 :(得分:11)

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

/home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null
Hello I'm a background task
/home/shellter $

答案 2 :(得分:9)

建立@ 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:~$

我不知道这背后的原因,但我记得在一篇旧文章中,disown阻止了bash输出过程ID。

答案 3 :(得分:6)

基于上述答案,如果您需要允许stderr通过命令:

f() { echo "Hello I'm a background task" >&2; }
{ f 2>&3 &} 3>&2 2>/dev/null

答案 4 :(得分:4)

尝试:

f

您已隐藏输出 PID 。请注意,您仍然可以从$ REPLY

中检索 PID

答案 5 :(得分:4)

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

我遇到了这个方法(子壳)和使用'等待'的问题。但是,当我在一个函数中运行它时,我能够做到这一点:

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秒的延迟。

答案 6 :(得分:4)

基于this answer,我想出了更简洁,更正确的方法:

silent_background() {
    { 2>&3 "$@"& } 3>&2 2>/dev/null
    disown &>/dev/null  # Prevent whine if job has already completed
}
silent_background date

答案 7 :(得分:1)

子shell解决方案有效,但我也希望能够等待后台作业(并且最后没有“完成”消息)。来自子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[*]}

很容易。