setsid 使程序脱离终端运行
直接使用 setsid cmd ...
$ ping ::1
root 399698 399637 0 14:51 pts/42 00:00:00 ping ::1
$ setsid ping ::1
root 399707 1 0 14:52 ? 00:00:00 ping ::1
注意看,现在它已经没有隶属任何进程组(父进程是init)和隶属的会话(没有控制终端pts/x),如果此刻退出bash会话,程序也会继续运行。
$ ls -l /proc/$$/fd/1
lrwx------ 1 root root 64 May 9 14:50 /proc/399648/fd/1 -> /dev/pts/43
$ ls -l /proc/399707/fd/1
lrwx------ 1 root root 64 May 9 15:21 /proc/399707/fd/1 -> '/dev/pts/1 (deleted)'
-c 参数
如果使用 -c 参数将控制终端设置为当前控制终端,则退出bash会话程序也会退出:
$ setsid -c ping ::1
root 399832 1 0 15:05 pts/1 00:00:00 ping ::1
-w 参数
-w 参数等待程序退出,并使用相同的返回,虽然^C中断的不是子程序,但是不会输出一行$PS1
$ setsid -w ping ::1
root 399934 399921 0 15:11 pts/42 00:00:00 setsid -w ping ::1
root 399935 399934 0 15:11 ? 00:00:00 ping ::1
将其父进程杀死,自动成为孤儿进程,被init进程收养:
$ kill 399934
root 399935 1 0 15:11 ? 00:00:00 ping ::1
使用 strace 连接到程序输出
$ strace -ewrite -p $PID
strace: Process 400030 attached
write(1, "64 bytes from ::1: icmp_seq=465 "..., 53) = -1 EIO (Input/output error)
$ strace -ewrite -p 400030 -s 53
strace: Process 400030 attached
write(1, "64 bytes from ::1: icmp_seq=513 ttl=64 time=0.077 ms\n", 53) = -1 EIO (Input/output error)
使用 reptyr 获取现有正在运行的程序并将其附加到新终端
项目地址:https://github.com/nelhage/reptyr
$ apt install reptyr
经测试,需要使用 -s 参数,否则只能获取普通会话的程序:
$ ping ::1
[1]+ Stopped ping ::1
$ reptyr 401086
64 bytes from ::1: icmp_seq=12 ttl=64 time=0.027 ms
$ setsid ping ::1
$ reptyr 401110
[-] Timed out waiting for child stop.
# 在目标上附加 fds 0-2,即使它没有附加到 tty。
$ reptyr -s 401110
[-] Timed out waiting for child stop.
64 bytes from ::1: icmp_seq=56 ttl=64 time=0.041 ms
64 bytes from ::1: icmp_seq=57 ttl=64 time=0.029 ms
64 bytes from ::1: icmp_seq=58 ttl=64 time=0.028 ms
--- ::1 ping statistics ---
61 packets transmitted, 61 received, 0% packet loss, time 61384ms
rtt min/avg/max/mdev = 0.016/0.027/0.041/0.004 ms
^C
内核参数错误:
$ reptyr 107572
Unable to attach to pid 107572: Operation not permitted
The kernel denied permission while attaching. If your uid matches
the target's, check the value of /proc/sys/kernel/yama/ptrace_scope.
For more information, see /etc/sysctl.d/10-ptrace.conf
需要有宽松的 ptrace 设置才能工作。这不是 ubuntu 上的默认设置,可以通过运行(作为 root)临时更改:
# echo 0 > /proc/sys/kernel/yama/ptrace_scope
可以通过编辑以下文件永久更改:/etc/sysctl.d /10-ptrace.conf
参考
https://www.linuxcool.com/setsid
https://stackoverflow.com/questions/715751/attach-to-a-processes-output-for-viewing