Como colocar um trabalho em segundo plano sem saída? [duplicado]

3

Ao colocar um trabalho em segundo plano com o comando bg , tenho a saída do comando do trabalho.

Como colocar o trabalho em segundo plano (como o comando bg ), mas sem nenhuma saída?

PS: o trabalho está vinculado a um comando com uma saída (não há >/dev/null 2>1 no comando original)

    
por user123456 12.03.2017 / 23:15

2 respostas

1

Você precisa dizer ao aplicativo agora em segundo plano para parar de escrever no dispositivo tty. Não há uma maneira genérica de fazer isso.

Você pode fazer:

stty tostop

para que as tarefas em segundo plano sejam suspensas (com um sinal SIGTTOU ) quando tentarem escrever no tty.

Você pode anexar um depurador ao processo e fazê-lo reabrir os descritores de arquivo que ele abriu no dispositivo tty para /dev/null . Like (aqui apenas para stdout):

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

(assumindo que o aplicativo esteja vinculado dinamicamente ou tenha símbolos de depuração e observe que alguns sistemas terão restrições de segurança que o impedem de fazê-lo).

Para aplicativos vinculados dinamicamente, você pode executá-los com um LD_PRELOAD blob que instala um manipulador em SIGTTOU (e faz o stty tostop ) que reabre stdout e stderr em /dev/null se eles estivessem indo para um terminal. Isso lida com o caso de aplicações não-setuid / setgid que escrevem no terminal através do seu stdout / stderr e não lidam com o próprio SIGTTOU.

Executar:

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

Onde handle_tostop.c contém:

#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);
}

E então:

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

Em vez de /dev/null , talvez você queira redirecionar a saída para algum arquivo de log (que talvez queira abrir com O_APPEND e possivelmente incluir o pid do processo no nome do arquivo para saber qual processo a saída é de) por isso não é descartada se for de alguma utilidade para você.

    
por 13.03.2017 / 16:55
0

Se você usar nohup seus trabalhos serão executados em segundo plano, mas isso criará uma saída automática (nohup.out).

    
por 13.03.2017 / 15:51