Linux 使用命令行在启动后重定向进程的 STDERR / STDOUT?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/593724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:03:05  来源:igfitidea点击:

Redirect STDERR / STDOUT of a process AFTER it's been started, using command line?

linuxbashshell

提问by Ian Kelling

In the shell you can do redirection, ><, etc., but how about AFTER a program is started?

在 shell 中,您可以执行重定向><等操作,但是在程序启动之后呢?

Here's how I came to ask this question, a program running in the background of my terminal keeps outputting annoying text. It's an important process so I have to open another shell to avoid the text. I'd like to be able to >/dev/nullor some other redirection so I can keep working in the same shell.

这就是我问这个问题的方式,在我的终端后台运行的程序不断输出烦人的文本。这是一个重要的过程,所以我必须打开另一个外壳以避免文本。我希望能够>/dev/null或其他一些重定向,以便我可以继续在同一个 shell 中工作。

采纳答案by vladr

Short of closing and reopening your tty (i.e. logging off and back on, which may also terminate some of your background processes in the process) you only have one choice left:

除了关闭和重新打开您的 tty(即注销并重新登录,这也可能会终止进程中的某些后台进程),您只剩下一个选择:

  • attach to the process in question using gdb, and run:
    • p dup2(open("/dev/null", 0), 1)
    • p dup2(open("/dev/null", 0), 2)
    • detach
    • quit
  • 使用 gdb 附加到有问题的进程,然后运行:
    • p dup2(open("/dev/null", 0), 1)
    • p dup2(open("/dev/null", 0), 2)
    • 分离
    • 退出

e.g.:

例如:

$ 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

(gdb) p dup2(open("/dev/null",0),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

You may also consider:

您还可以考虑:

  • using screen; screen provides several virtual TTYs you can switch between without having to open new SSH/telnet/etc, sessions
  • using nohup; this allows you to close and reopen your session without losing any background processes in the... process.
  • 使用screen; screen 提供了几个虚拟 TTY,您可以在无需打开新的 SSH/telnet/etc、会话的情况下在它们之间切换
  • 使用nohup; 这使您可以关闭并重新打开会话,而不会丢失...进程中的任何后台进程。

回答by Roger Lipscombe

Not a direct answer to your question, but it's a technique I've been finding useful over the last few days: Run the initial command using 'screen', and then detach.

不是对您问题的直接回答,但这是我在过去几天中发现有用的一种技术:使用“屏幕”运行初始命令,然后分离。

回答by naugtur

This will do:

这将:

strace -ewrite -p $PID

It's not that clean (shows lines like: write(#,<text you want to see>)), but works!

它不是那么干净(显示如下行:)write(#,<text you want to see>),但有效!



You might also dislike the fact that arguments are abbreviated. To control that use the -sparameter that sets the maximum length of strings displayed.

您可能也不喜欢参数被缩写的事实。要控制使用-s设置显示的字符串的最大长度的参数。

It catches all streams, so you might want to filter that somehow:

它捕获所有流,因此您可能希望以某种方式对其进行过滤:

strace -ewrite -p $PID 2>&1 | grep "write(1" 

shows only descriptor 1 calls. 2>&1is to redirect STDERR to?STDOUT, as stracewrites to STDERR by default.

仅显示描述符 1 调用。2>&1是将 STDERR 重定向到?STDOUT,strace默认情况下写入 STDERR。

回答by Mirek

Redirect output from a running process to another terminal, file or screen:

将正在运行的进程的输出重定向到另一个终端、文件或屏幕:

tty
ls -l /proc/20818/fd
gdb -p 20818

Inside gdb:

内部gdb

p close(1)
p open("/dev/pts/4", 1)
p close(2)
p open("/tmp/myerrlog", 1)
q

Detach a running process from bashterminal and keep it alive:

bash终端分离正在运行的进程并使其保持活动状态:

[Ctrl+z]
bg %1 && disown %1
[Ctrl+d]

Explanation:

解释:

20818 - just an example of running process pid
p - print result of gdb command
close(1) - close standard output
/dev/pts/4 - terminal to write to
close(2) - close error output
/tmp/myerrlog - file to write to
q - quit gdb
bg %1 - run stoped job 1 on background
disown %1 - detach job 1 from terminal

20818 - 只是运行进程 pid
p 的一个例子- 打印 gdb 命令的结果
close(1) - 关闭标准输出
/dev/pts/4 - 写入
close(2) 的终端- 关闭错误输出
/tmp/myerrlog - 文件到写入
q - 退出 gdb
bg %1 - 在后台运行停止的作业 1
disown %1 - 从终端分离作业 1

回答by jcomeau_ictx

riffing off vladr's (and others') excellent research:

重复 vladr(和其他人)的出色研究:

create the following two files in the same directory, something in your path, say $HOME/bin:

在同一个目录中创建以下两个文件,在你的路径中,比如 $HOME/bin:

silence.gdb, containing (from vladr's answer):

沉默.gdb,包含(来自vladr的回答):


p dup2(open("/dev/null",0),1)
p dup2(open("/dev/null",0),2)
detach
quit

and silence, containing:

和沉默,包括:


#!/bin/sh
if [ "

chmod +x ~/bin/silence  # make the script executable
" -a "" ]; then gdb -p -x

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 else echo Must specify PID of process to silence >&2 fi
#!/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 }')
        echo "log file set to $LOG_FILE"
    fi
}

reloadLog

Now, next time you forget to redirect firefox, for example, and your terminal starts getting cluttered with the inevitable "(firefox-bin:5117): Gdk-WARNING **: XID collision, trouble ahead" messages:

现在,例如,下次您忘记重定向 firefox 并且您的终端开始被不可避免的“(firefox-bin:5117):Gdk-WARNING **:XID 冲突,前方有麻烦”消息弄得乱七八糟:

reredirect -m FILE PID

You could also redirect gdb's output to /dev/null if you don't want to see it.

如果您不想看到它,也可以将 gdb 的输出重定向到 /dev/null。

回答by Mostafa Nazari

this is bash script part based on previous answers, which redirect log file during execution of an open process, it is used as postscript in logrotateprocess

这是基于先前答案的 bash 脚本部分,它在打开进程的执行期间重定向日志文件,它用作logrotate进程中的后记

relink PID
relink PID | grep usefull_content

回答by eMPee584

Dupxis a simple *nix utility to redirect standard output/input/error of an already running process.

Dupx是一个简单的 *nix 实用程序,用于重定向已运行进程的标准输出/输入/错误。

https://www.isi.edu/~yuri/dupx/

https://www.isi.edu/~yuri/dupx/

回答by Jér?me Pouiller

You can use reredirect (https://github.com/jerome-pouiller/reredirect/).

您可以使用重定向(https://github.com/jerome-pouiller/reredirect/)。

Type

类型

##代码##

and outputs (standard and error) will be written in FILE.

和输出(标准和错误)将写入文件。

reredirect README also explains how to restore original state of process, how to redirect to another command or to redirect only stdout or stderr.

reredirect README 还解释了如何恢复进程的原始状态,如何重定向到另一个命令或仅重定向 stdout 或 stderr。

reredirectalso provide a script called relinkthat allows to redirect to current terminal:

reredirect还提供一个名为relink允许重定向到当前终端的脚本:

##代码##

(reredirect seems to have same features than Dupx described in another answer but, it does not depends on Gdb).

(重定向似乎与另一个答案中描述的 Dupx 具有相同的功能,但它不依赖于 Gdb)。