我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
当它按预期执行时,例如command >1
(>1
在你的bg; %+ >1 /dev/null
例子中不会1
) 将把标准输出定向到当前工作目录中命名的实际文件。要指向文件描述符,
>&FDNUMBER
请使用...FDNUMBER
文件描述符的编号在哪里,例如>&2
(将 STDOUT 直接发送到 STDERR) 或者2>&1
(将 STDERR 直接发送到 STDOUT)。要操作和指导一个已经运行的进程的文件描述符,有几种不同的方法,具体来说使用 GDB,在我的回答中让使用脚本启动的正在运行的进程退出(MineCraft 服务器)。