<div class="gmail_quote">On Tue, Jun 15, 2010 at 8:08 PM, gvim <span dir="ltr"><<a href="mailto:gvimrc@gmail.com">gvimrc@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Supposing I'm connected remotely to a server process via SSH and I lose that connection. The process is still running and it's ID is available via top or ps but can I get its output back into a tty? If so, how?<br>
</blockquote></div><br>You can attach to the process with a debugger, open a new tty and then dup stdin/stdout/stderr to the new tty. I once wrote a shell script to automate this process. It does work - however not always for various reasons.<br>
<br>note: it needs /dev/ttypX /dev/ptypX devices so if you don't have those (modern linux distributions tend to only come with /dev/pmtx) you'll need to create one first using:<br><br>mknod /dev/ptyp1 c 2 1<br>mknod /dev/ttyp1 c 3 1<br>
<br>Once that's done, connect a terminal program (minicom or similar) to /dev/ptyp1 and run this script. The process should appear inside minicom under control of the new pseudo tty.<br><br>Rob<br><br><pre>#!/bin/bash<br>
#<br># hijack.sh - A script for migrating a process from one terminal to another.<br>#             by Robert McKay <<a href="mailto:robert@mckay.com">robert@mckay.com</a>><br>#<br>#<br># Start a terminal program on /dev/ptyp1. This must be done first.<br>
# Locate the pid of the process you are trying to gank<br># <br># Take a deep breath...<br>#<br># Then run:<br># ./this.sh <pid><br>#<br># You should now have a new fork() of the original program (inc. state and<br>
# open fd's) under the control of your terminal program. The original (parent)<br># side of the fork should have exit'd. It's like using 'screen' except you<br># don't have to think of it in advance.<br>
#<br><br>pid=$1<br>(<br>  echo 'set follow-fork-mode child'<br>  echo 'call signal(1, 1)' # block HUP signal from the disconnecting terminal<br>  echo 'call raise(17)' # not sure if this really helps<br>
  echo 'call fork()' <br>  echo 'call kill('$pid', 9)'<br>  sleep 1 <br>  echo 'call setsid()'<br>  echo 'call close(0)'<br>  echo 'call open("/dev/ttyp1", 66, 0666)'<br>
  echo 'call dup2(0, 1)'<br>  echo 'call dup2(0, 2)'<br>  echo 'call dup2(0, 4)'<br>  echo 'call dup2(0, 5)'<br>  echo 'call dup2(0, 6)'<br>  echo 'call ioctl(0, 21518, 0)' # set new controlling terminal<br>
  echo 'call signal(1, $1)' # replace signal handler<br>  echo 'detach'<br>  sleep 3<br>) | gdb -q -p $pid -x -<br></pre><br>