如何停止后台作业输出到终端?

如何停止后台作业输出到终端?

make在我的 Pi 上的 Kismet 终端中运行了一次,它每 10 到 15 秒就会向终端输出一次,无论它是否在后台运行。

我尝试使用CTRL+Z并运行bg命令。尽管 jobs 命令将其列为Running并将命令列为以make &表明它在后台,但输出仍会传到终端。

我也再次暂停它,然后跑去bg; %+ >1 /dev/null尝试将其发送STDOUT/dev/null,但它仍然输出到屏幕。

有没有办法让作业在后台运行并仅将STDERR消息发送到终端?

输出如下:

第一次尝试:

[1]+  Stopped                 make
root@stormpi:/usr/local/kismet# jobs
[1]+  Stopped                 make
root@stormpi:/usr/local/kismet# bg
[1]+ make &
root@stormpi:/usr/local/kismet# jobs
[1]+  Running                 make &
root@stormpi:/usr/local/kismet# In file included from entrytracker.h:36,
                 from system_monitor.cc:33:
trackedelement.h: In member function ‘void tracker_element_core_vector<T, TT>::set(tracker_element_core_vector<T, TT>::const_iterator, tracker_element_core_vector<T, TT>::const_iterator) [with T = double; tracker_type TT = (tracker_type)22]’:
trackedelement.h:1553:18: note: parameter passing for argument of type ‘tracker_element_core_vector<double, (tracker_type)22>::const_iterator’ {aka ‘__gnu_cxx::__normal_iterator<const double*, std::vector<double> >’} changed in GCC 7.1
     virtual void set(const_iterator a, const_iterator b) {
                  ^~~
trackedelement.h:1553:18: note: parameter passing for argument of type ‘tracker_element_core_vector<double, (tracker_type)22>::const_iterator’ {aka ‘__gnu_cxx::__normal_iterator<const double*, std::vector<double> >’} changed in GCC 7.1

第二次尝试:

jobs
[1]+  Running                 make &
root@stormpi:/usr/local/kismet# fg
make
^Z
[1]+  Stopped                 make
root@stormpi:/usr/local/kismet# jobs
[1]+  Stopped                 make
root@stormpi:/usr/local/kismet# bg; %+ >1 /dev/null
[1]+ make &
make
g++ -std=gnu++17 -MM -MP -Wall -Wno-unknown-warning-option -Wno-deprecated-declarations -Wno-format-truncation -Wno-unused-local-typedefs -Wno-unused-function -Wno-infinite-recursion -g -I. -fPIE -g -O2 -O3 -pthread -DKS_STR_ENCODING_NONE    -MT gpsgpsd_v3.cc.o gpsgpsd_v3.cc -MF gpsgpsd_v3.cc.d
g++ -std=gnu++17 -Wall -Wno-unknown-warning-option -Wno-deprecated-declarations -Wno-format-truncation -Wno-unused-local-typedefs -Wno-unused-function -Wno-infinite-recursion -g -I. -fPIE -g -O2 -O3 -pthread -DKS_STR_ENCODING_NONE    -c gpsgpsd_v3.cc -o gpsgpsd_v3.cc.o

答案1

您收到的这些消息很可能打印到标准错误而不是标准输出...您可以通过如下方式make运行来验证哪个是哪个:strace

strace -e write make ...

然后查看文件描述符(write()调用中的第一个参数)... 2 是标准错误,1 是标准输出。

要隐藏这些消息,您可能需要将标准输出(文件描述符 1) 和标准误差(文件描述符 2) 到/dev/null或另一个文件)在命令执行之前,如下所示:

make ... > /dev/null 2>&1 &

不是像这样:

make ... 2>&1 > /dev/null &

Bash 中的重定向...具体来说以下摘录:

请注意,重定向的顺序很重要。例如,命令

ls > dirlist 2>&1将标准输出(文件描述符 1)和标准错误(文件描述符 2)定向到文件 dirlist,而命令

ls 2>&1 > dirlist仅将标准输出定向到文件 dirlist,因为在将标准输出重定向到 dirlist 之前,标准错误已成为标准输出的副本。

在 bash 中定向 STDOUT 和 STDERR 的另一种方法是使用&>例如如下:

make ... &> /dev/null &

要仅引导 STDOUT,请使用如下>方法:

make ... > /dev/null &

您可能希望直接转到日志文件以供以后检查,而不是/dev/null,在这种情况下,您可能需要使用追加运算符>>,例如像这样定向 STDOUT:

make ... >> file.log &

或者直接使用 STDOUT 和 STDERR,例如像这样:

make ... &>> file.log &

补充说明

  1. >1当它按预期执行时,例如command >1>1在你的bg; %+ >1 /dev/null例子中不会1) 将把标准输出定向到当前工作目录中命名的实际文件。

  2. 要指向文件描述符,>&FDNUMBER请使用...FDNUMBER文件描述符的编号在哪里,例如>&2将 STDOUT 直接发送到 STDERR) 或者2>&1将 STDERR 直接发送到 STDOUT)。

  3. 要操作和指导一个已经运行的进程的文件描述符,有几种不同的方法,具体来说使用 GDB,在我的回答中让使用脚本启动的正在运行的进程退出(MineCraft 服务器)

相关内容