commandを使用してジョブをバックグラウンドに配置すると、jobコマンドの出力がありますbg
。
bg
コマンドのようにバックグラウンドにタスクを配置しますが、出力がない方法は何ですか?
>/dev/null 2>1
PS:ジョブは出力のあるコマンドにリンクされます(元のコマンドにはありません)
答え1
ttyデバイスへの書き込みを中止するには、現在バックグラウンドにあるアプリケーションに通知する必要があります。これを行う普遍的な方法はありません。
あなたはできます:
stty tostop
SIGTTOU
ttyに書き込もうとすると、バックグラウンドジョブは(信号とともに)中断されます。
デバッガをプロセスに接続し、ttyデバイスで開いたファイルディスクリプタを再度開くようにできます/dev/null
。次のようになります(ここではstdoutのみ)。
gdb --batch -ex 'call close(1)' -ex 'call open("/dev/null",2)' -p "$pid"
(アプリケーションが動的にリンクされているかデバッグシンボルがあると仮定し、一部のシステムにはこれを防ぐセキュリティ制限があることに注意してください。)
動的に接続されたアプリケーションの場合、LD_PRELOAD
SIGTTOUにハンドラをインストールして実行する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
破棄されません)。
答え2
使用する場合北面ジョブはバックグラウンドで実行されますが、自動出力(nohup.out)が生成されます。