web-dev-qa-db-ja.com

出力なしでジョブをバックグラウンドに置く方法は?

コマンドbgを使用してジョブをバックグラウンドに置くと、ジョブのコマンドの出力が表示されます。

ジョブをバックグラウンドに置く方法(bgコマンドなど)ですが、出力はありませんか?

PS:ジョブは出力付きのコマンドにリンクされています(元のコマンドには>/dev/null 2>1はありません)

3
user123456

バックグラウンドになっているアプリケーションに、ttyデバイスへの書き込みを停止するように指示する必要があります。それを行う一般的な方法はありません。

できるよ:

_stty tostop
_

バックグラウンドジョブがttyに書き込もうとしたときに(SIGTTOUシグナルで)中断されるようにするため。

デバッガーをプロセスに接続して、ttyデバイスで開いているファイル記述子を_/dev/null_に再度開くようにすることができます。のように(ここではstdoutのみ):

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

(アプリケーションが動的にリンクされているか、デバッグシンボルがあると仮定し、一部のシステムにはセキュリティ制限があり、それを実行できないことに注意してください)。

動的にリンクされたアプリケーションの場合、SIGTTOUにハンドラーをインストールする_LD_PRELOAD_ blobを使用して実行できます(また、_stty tostop_でstdoutとstderrを再度開く_/dev/null_を実行します)。ターミナル。これは、非setuid/setgidアプリケーションがstdout/stderrを介して端末に書き込む場合を処理し、SIGTTOU自体は処理しません。

実行:

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

_handle_tostop.c_に含まれる場所:

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

その後:

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

_/dev/null_の代わりに、出力をログファイルにリダイレクトしたい場合があります(その後、_O_APPEND_で開き、ファイル名にプロセスのpidを含めて、誰が誰であるかがわかるようにします。からの出力を処理するので、役に立ったとしても破棄されません。

1

Nohup を使用すると、ジョブはバックグラウンドで実行されますが、これにより自動出力(Nohup.out)が作成されます。

0
Newton San.