在外壳中,您可以执行重定向>
<
等操作,但是启动程序后如何处理?
这就是我问这个问题的方式,在我的终端后台运行的程序不断输出令人讨厌的文本。这是一个重要的过程,因此我必须打开另一个shell以避免输入文本。我希望能够进行>/dev/null
重定向或其他重定向,以便可以在同一外壳中继续工作。
在外壳中,您可以执行重定向>
<
等操作,但是启动程序后如何处理?
这就是我问这个问题的方式,在我的终端后台运行的程序不断输出令人讨厌的文本。这是一个重要的过程,因此我必须打开另一个shell以避免输入文本。我希望能够进行>/dev/null
重定向或其他重定向,以便可以在同一外壳中继续工作。
Answers:
除非关闭并重新打开tty(即注销并重新登录,这可能还会终止该过程中的某些后台进程),否则您只剩下一个选择:
例如:
$ tail -f /var/log/lastlog &
[1] 5636
$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/pts/0
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog
$ gdb -p 5636
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Attaching to process 5636
Reading symbols from /usr/bin/tail...(no debugging symbols found)...done.
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 0x7f3c8f5a66e0 (LWP 5636)]
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
(no debugging symbols found)
0x00007f3c8eec7b50 in nanosleep () from /lib/libc.so.6
(gdb) p dup2(open("/dev/null",0),1)
[Switching to Thread 0x7f3c8f5a66e0 (LWP 5636)]
$1 = 1
(gdb) p dup2(open("/dev/null",0),2)
$2 = 2
(gdb) detach
Detaching from program: /usr/bin/tail, process 5636
(gdb) quit
$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/null
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog
lr-x------ 1 myuser myuser 64 Feb 27 07:36 4 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 5 -> /dev/null
您还可以考虑:
screen
; 屏幕提供了几个虚拟TTY,您可以在不打开新的SSH / telnet / etc,会话的情况下进行切换nohup
; 这样,您就可以关闭并重新打开会话,而不会丢失...进程中的任何后台进程。open("/path/to/new/stdout",O_WRONLY)
。但是O_WRONLY可能不可用;它的值1
在Linux / glibc上。
1025
激活O_APPEND
除了O_WRONLY
,如果你既重定向标准错误和标准输出到同一个文件,该文件是很方便的。
这样可以:
strace -ewrite -p $PID
它不是很干净(显示类似:的行write(#,<text you want to see>)
),但是可以工作!
您可能还不喜欢参数被缩写的事实。要控制该-s
参数,请使用设置显示的最大字符串长度的参数。
它捕获所有流,因此您可能希望以某种方式对其进行过滤:
strace -ewrite -p $PID 2>&1 | grep "write(1"
仅显示描述符1调用。2>&1
是将STDERR重定向到STDOUT,strace
默认情况下是写入STDERR。
sudo
需要。
梳理弗拉德(和其他人)的出色研究:
在同一目录中创建以下两个文件,在路径中输入$ HOME / bin:
silence.gdb,包含(来自vladr的答案):
p dup2(open("/dev/null",0),1)
p dup2(open("/dev/null",0),2)
detach
quit
和沉默,包含:
#!/bin/sh
if [ "$0" -a "$1" ]; then
gdb -p $1 -x $0.gdb
else
echo Must specify PID of process to silence >&2
fi
chmod +x ~/bin/silence # make the script executable
现在,例如,下次您忘记重定向firefox时,您的终端将开始不可避免地出现“(firefox-bin:5117):Gdk-WARNING **:XID冲突,前面有麻烦”的消息:
ps # look for process xulrunner-stub (in this case we saw the PID in the error above)
silence 5117 # run the script, using PID we found
如果您不想看到gdb的输出,也可以将其重定向到/ dev / null。
--batch-silent
,它可以抑制输出,并且如果出现问题(例如缺少进程),则不会将您转储到gdb控制台中。顺便说一句,$!
指的是最新的后台作业,但我认为它不能在脚本本身中使用。我使用别名: alias silencebg='silence $!'
将正在运行的进程的输出重定向到另一个终端,文件或屏幕:
tty
ls -l /proc/20818/fd
gdb -p 20818
在gdb内部:
p close(1)
p open("/dev/pts/4", 1)
p close(2)
p open("/tmp/myerrlog", 1)
q
从bash终端分离一个正在运行的进程,并使其保持活动状态:
[Ctrl+z]
bg %1 && disown %1
[Ctrl+d]
说明:
20818-只是运行进程pid
p 的示例-gdb 命令的打印结果
close(1)-关闭标准输出
/ dev / pts / 4-终端写入
close(2)-关闭错误输出
/ tmp / myerrlog-文件至写入
q-退出gdb
bg%1-在后台运行停止的作业1
取消%1-从终端分离作业1
stdin
(文件描述符0
)被关闭,这将不起作用。
p open("/tmp/myerrlog", 2)
?
这是基于以前的答案,其中一个开放的过程的执行过程中重定向日志文件的bash脚本的一部分,它被用作后记logrotate
过程
#!/bin/bash
pid=$(cat /var/run/app/app.pid)
logFile="/var/log/app.log"
reloadLog()
{
if [ "$pid" = "" ]; then
echo "invalid PID"
else
gdb -p $pid >/dev/null 2>&1 <<LOADLOG
p close(1)
p open("$logFile", 1)
p close(2)
p open("$logFile", 1)
q
LOADLOG
LOG_FILE=$(ls /proc/${pid}/fd -l | fgrep " 1 -> " | awk '{print $11}')
echo "log file set to $LOG_FILE"
fi
}
reloadLog
Dupx是一个简单的* nix实用程序,用于重定向已经运行的进程的标准输出/输入/错误。
您可以使用重定向(https://github.com/jerome-pouiller/reredirect/)。
类型
reredirect -m FILE PID
输出(标准和错误)将写入FILE。
reredirect README还说明了如何还原进程的原始状态,如何重定向到另一个命令或仅重定向stdout或stderr。
reredirect
还提供了一个名为的脚本relink
,该脚本允许重定向到当前终端:
relink PID
relink PID | grep usefull_content
(重定向似乎与另一个答案中描述的Dupx具有相同的功能,但它不依赖于Gdb)。