3

When putting a job in background with the command bg, I have the output of the command of the job.

How to put the job in background (like the bg command) but without any output?

PS: the job is linked to a command with an output (there is no >/dev/null 2>1 in the original command)

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
user123456
  • 5,018
  • 2
    @Gilles This looks a bit different. I think they want to &> /dev/null after they have already typed in the command, while also putting it in bg. – Sparhawk Mar 13 '17 at 04:49
  • @roaima, it's a completely different question. Even if some of the answers there would apply here, there may very well be answers that would apply here and not there. – Stéphane Chazelas Mar 13 '17 at 15:21
  • @StéphaneChazelas I don't see that, but I'll withdraw my close vote and let others decide – Chris Davies Mar 13 '17 at 15:26
  • Is the job already running, or do you want to start it in the background without output? – Chris Davies Mar 13 '17 at 15:27

2 Answers2

1

You need to tell the now backgrounded application to stop writing on the tty device. There is no generic way to do that.

You can do:

stty tostop

to make so that background jobs be suspended (with a SIGTTOU signal) when they try to write to the tty.

You can attach a debugger to the process and make it re-open the file descriptors it has open on the tty device to /dev/null. Like (here for stdout only):

gdb --batch -ex 'call close(1)' -ex 'call open("/dev/null",2)' -p "$pid"

(assuming the application is dynamically linked or has debug symbols and note that some systems will have security restrictions preventing you from doing it).

For dynamically linked applications, you could run them with a LD_PRELOAD blob that installs a handler on SIGTTOU (and do the stty tostop) that reopens stdout and stderr on /dev/null if they were going to a terminal. That would handle the case of non-setuid/setgid applications writing on the terminal via their stdout/stderr and don't handle SIGTTOU themselves.

Run:

 gcc -Wall -shared -fPIC -nostartfiles -o ~/lib/handle_tostop.so handle_tostop.c

Where handle_tostop.c contains:

#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

static void reopen_on_null(int req_fd)
{
  int fd;
  if (close(req_fd) == 0) {
    fd = open("/dev/null", O_RDWR);
    if (fd != req_fd && fd >= 0) {
      dup2(fd, req_fd);
      close(fd);
    }
  }
}

static void handle_sigttou(int sig)
{
  if (isatty(1)) reopen_on_null(1);
  if (isatty(2)) reopen_on_null(2);
}
void _init()
{
  signal(SIGTTOU, handle_sigttou);
}

And then:

LD_PRELOAD=~/lib/handle_tostop.so
export LD_PRELOAD
stty tostop

Instead of /dev/null, you may want to redirect the output to some log file (which you might then want to open with O_APPEND, and possibly include the pid of the process in the file name so you know whose process the output is from) so it's not discarded if it's of any use to you.

0

If you use nohup your jobs will run in background, but this create a automatic output (nohup.out).

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255