简体   繁体   中英

How to change the file descriptors of a process?

I have a process running which used to write to PATH/somefile.log

The somefile.log has been deleted and now when I check the /proc/PID/fd/1 I can see 1 redirects to PATH/somefile.log (deleted)

I want to redirect STDIN/STDERR to a different ondisk, existing file without bouncing the process.

Is that possible?

You can do that by using ptrace on the process to dup2 a new FD over the old one. The most convenient way to do that would be to attach to the process with gdb . Here's how:

$ cat > q72953752.c 
#include <stdio.h>

int main(void) {
    puts("Hello");
    fflush(stdout);
    getchar();
    puts("World");
}
$ gcc q72953752.c 
$ ./a.out > oldfile.txt

Now open a second terminal:

$ gdb
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 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".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) attach 120681
Attaching to process 120681
Reading symbols from /tmp/a.out...
(No debugging symbols found in /tmp/a.out)
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
Reading symbols from /usr/lib/debug/.build-id/18/78e6b475720c7c51969e69ab2d276fae6d1dee.debug...
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/45/87364908de169dec62ffa538170118c1c3a078.debug...
0x00007fb55d298fd2 in __GI___libc_read (fd=0, buf=0x55635ad966b0, nbytes=1024) at ../sysdeps/unix/sysv/linux/read.c:26
26      ../sysdeps/unix/sysv/linux/read.c: No such file or directory.
(gdb) call (int)open("newfile.txt", 01|0100|02000, 0666)
$1 = 3
(gdb) call (int)dup2(3, 1)
$2 = 1
(gdb) call (int)close(3)
$3 = 0
(gdb) q
A debugging session is active.

        Inferior 1 [process 120681] will be detached.

Quit anyway? (y or n) y
Detaching from program: /tmp/a.out, process 120681
[Inferior 1 (process 120681) detached]
$ 

01|0100|02000 there means O_WRONLY|O_CREAT|O_APPEND ; I used the former because you can't use #define constants in GDB like that.

Now switch back to the first terminal and hit Enter:


$ cat oldfile.txt
Hello
$ cat newfile.txt 
World
$ 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM