当前位置: 首页 > 面试题库 >

如何重定向已经运行的进程的输出

严天逸
2023-03-14
问题内容

通常我会像这样启动一个命令

longcommand &;

我知道您可以通过执行以下操作来重定向它

longcommand > /dev/null;

例如摆脱输出或

longcommand 2>&1 > output.log

捕获输出。

但是我有时会忘记,并且想知道事实之后是否有办法捕获或重定向。

longcommand
ctrl-z
bg 2>&1 > /dev/null

或类似的内容,这样我就可以继续使用终端,而不会在终端上弹出消息。


问题答案:

请参阅 从正在运行的进程重定向输出

首先,我cat > foo1在一个会话中运行命令,并测试将来自stdin的数据复制到文件中。然后在另一个会话中,我重定向输出。

首先找到该过程的PID:

$ ps aux | grep cat
rjc 6760 0.0 0.0 1580 376 pts/5 S+ 15:31 0:00 cat

现在检查文件句柄是否已打开:

$ ls -l /proc/6760/fd
total 3
lrwx—— 1 rjc rjc 64 Feb 27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 Feb 27 15:32 1 -> /tmp/foo1
lrwx—— 1 rjc rjc 64 Feb 27 15:32 2 -> /dev/pts/5

现在运行GDB:

$ gdb -p 6760 /bin/cat
GNU gdb 6.4.90-debian

[license stuff snipped]

Attaching to program: /bin/cat, process 6760

[snip other stuff that's not interesting now]

(gdb) p close(1)
$1 = 0
(gdb) p creat("/tmp/foo3", 0600)
$2 = 1
(gdb) q
The program is running. Quit anyway (and detach it)? (y or n) y
Detaching from program: /bin/cat, process 6760

pGDB中的命令将打印一个表达式的值,一个表达式可以是要调用的函数,也可以是系统调用……所以我执行一个close()系统调用并传递文件句柄1,然后执行一个creat()系统调用以打开一个新的文件。的结果creat()为1,表示它替换了先前的文件句柄。如果我想对stdout和stderr使用相同的文件,或者想用其他数字替换文件句柄,则需要调用dup2()系统调用以实现该结果。

在此示例中,我选择使用creat()而不是,open()因为参数较少。用于标志的C宏无法从GDB使用(它不使用C头),因此我必须阅读头文件才能发现这一点–这样做并不难,但会花费更多时间。请注意,0600是具有读/写访问权限的所有者以及该组和其他没有访问权限的所有者的八进制权限。为该参数使用0并稍后在文件上运行chmod也是可行的。

之后,我验证结果:

ls -l /proc/6760/fd/
total 3
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 2008-02-27 15:32 1 -> /tmp/foo3 <====
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 2 -> /dev/pts/5

输入更多数据会cat导致文件/tmp/foo3被追加。

如果要关闭原始会话,则需要为其关闭所有文件句柄,打开一个可以作为控制tty的新设备,然后调用setsid()



 类似资料:
  • #include <stdio.h> #include <pthread.h> void *thread_func(void *p_arg) { while (1) { printf("%s\n", (char*)p_arg); sleep(10); } } int main(void)

  • 问题内容: 我想从Groovy程序中执行foo.bat,并将生成的进程的输出重定向到stdout。Java或Groovy代码示例都可以。 foo.bat可能需要花费几分钟才能运行并生成大量输出,因此我希望在生成后立即查看输出,而不是必须等到该过程完成之后才能立即查看所有输出。 问题答案: 它使用一个类读取执行的程序生成的所有输出,并将其显示在其自己的stdout中。

  • 问题内容: 我有一个简单的BASH命令,看起来像 运行此命令时,输出会输出到终端,而数据文件(out.dat)不会输出任何内容 我希望标准输出能够像直接执行命令那样重定向到out.dat 问题答案: 删除分号。 建议 同样按照Fredrik Pihl的建议,在不需要二进制二进制文件时,或者至少在实际上不使用它们时,请尽量不要使用它们: 另外,请注意可能导致路径名扩展的输出。 将显示文件而不只是文字

  • 问题内容: 我在命令行中执行的操作: 我想用python做什么: 问题答案: 更新:不鼓励使用,尽管在Python 3中仍然可用。 用途 如果你确实要使用子流程,请使用以下解决方案(大部分内容来自子流程的文档): OTOH,你可以完全避免系统调用:

  • 问题内容: 我正在探索Redis做发布/订阅。我想编写一个脚本,该脚本使用redis-cli订阅频道并转储发布到文件的所有内容。但是我注意到的是redis-cli subscripe channel>输出效果不佳。 非常感谢您的帮助。 问候,Kashyap 问题答案: 这是因为当redis-cli显示与订阅关联的消息时,不会自动刷新标准输出。因此,停止redis-cli之前的最后一条消息不会出现在

  • 问题内容: 如何使用JavaScript从另一个页面重定向到页面? 问题答案: 要重定向到另一个页面,可以使用: