出力せずにバックグラウンドにジョブを配置する方法は? [コピー]

出力せずにバックグラウンドにジョブを配置する方法は? [コピー]

commandを使用してジョブをバックグラウンドに配置すると、jobコマンドの出力がありますbg

bgコマンドのようにバックグラウンドにタスクを配置しますが、出力がない方法は何ですか?

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

ベストアンサー1

ttyデバイスへの書き込みを中止するには、現在バックグラウンドにあるアプリケーションに通知する必要があります。これを行う普遍的な方法はありません。

あなたはできます:

stty tostop

SIGTTOUttyに書き込もうとすると、バックグラウンドジョブは(信号とともに)中断されます。

デバッガをプロセスに接続し、ttyデバイスで開いたファイルディスクリプタを再度開くようにできます/dev/null。次のようになります(ここではstdoutのみ)。

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

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

動的に接続されたアプリケーションの場合、LD_PRELOADSIGTTOUにハンドラをインストールして実行するBLOBを使用して実行し、stty tostop端末にアクセスしたい場合は、stdoutとstderrを再度開くことができます。/dev/nullこれはstdout / stderrを介して端末に書き込む非setuid / setgidアプリケーションの場合を処理し、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破棄されません)。

おすすめ記事