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

新手上路,请多包涵

在shell中你可以做重定向, > < 等等,但是在程序启动之后呢?

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

原文由 Ian Kelling 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 885
2 个回答

如果没有关闭并重新打开您的 tty(即注销并重新打开,这也可能会终止进程中的一些后台进程),您只有一个选择:

  • 使用 gdb 附加到有问题的进程,然后运行:
    • p dup2(open(“/dev/null”, 0), 1)
    • p dup2(open(“/dev/null”, 0), 2)
    • 分离
    • 退出

例如:

 $ 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 ; screen 提供了几个虚拟 TTY,您可以在无需打开新的 SSH/telnet/etc、会话的情况下进行切换
  • 使用 nohup ;这使您可以关闭并重新打开会话,而不会丢失…进程中的任何后台进程。

原文由 vladr 发布,翻译遵循 CC BY-SA 3.0 许可协议

这将做:

 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。

原文由 naugtur 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题