Updated 2010-05-05 09:00:22 by lars_h

Ro July 3, 2003: This is one of those gems that you don't come across very often. When you do find it, you're immediately enamored with it, your heart flutters, and a single tear rolls down your cheek. You find yourself pumping your fists in a fit of joy, and you cannot believe your good fortune. Atheists beware, because you might find yourself seriously considering switching teams.

Don Libes, creator of cgi.tcl, also wrote expect, and this script is a part of the expect distribution. It allows you to run a process that is immune to client-server disconnections and that is ever-present and eternally running.

I disconnect my bash shell with
  dislocate bash

Then a new bash shell starts up and I start running processes and doing my thing. I get my emacs going and open a zillion buffers. Woe to the server that hosts my emacs.

Now, even though I'm on broadband, and so is the granny next door, my connection is flaky. So let's say my ssh connection to that server goes kaput; what happens? No loss, babe. (I'm running emacs through the bash shell, the dislocated sh process is just for show and tell.)
   $ dislocate
  connectable processes:
   #   pid      date started      process
   1   9925  Thu Jul 03 15:12:35  sh
   2   9768  Thu Jul 03 15:04:09  bash
  enter # or pid:

I log back in via ssh, and !booya! dislocate lets me connect back up to the bash shell. My connection went kaput while I was in emacs, and can you BELIEVE IT I'm back in emacs at the exact same line with my gazillion buffers in the EXACT same way. A little ^L goes a long way to repaint my screen because my emacs needs some tender care and feeding.

Now I've just touched on this proggy (since I discovered it about an hour ago), but man is it neato. Oh and if you try and run a program that doesn't exist, you might get some flaky behavior. See your .dislocate file and remove the flaky program because something weird happens. But hey.

All in all, dislocate is beautiful.

P.S. Once you get the hang of dislocate, the source of it is very very small, hack it up, and automate things with tcl (see the manpage for some examples) .


Functional competitors: VNC; old-time screen [1]; ... [someone should compare these]

TV This reminds me of my connection server I made on HP-UX and solaris about a decade ago (then again, linux is a gem coming from say 30 years ago? and it does a lot of reg expr stuff efficient, relatively bug free and streaming on top of it) intended to make interprocess, including text based, communication easier by having a single process where all relevant sockets are connected to, and which through file(socket) pointer passing makes connections between various parties by associating connection names. It would allow one end of a socket (strictly I think I started with unix pipes) connection to be disconnected but kept in existence by the connection server, until it would be passed to the appropriate process to be read from and written to.

I'm not sure linux, and maybe even windows allows file/socket pointer passing at the os layer, otherwise it could be an interesting redo. An additional advantage was to be able to connect processes in different process groups at different hierarchy level transparently.

[wpaulson] Dislocate (with slight modification) can also be used as part of a web-based interface to a command-line-based program that has a significant startup delay, e.g. a debugger. The startup delay need only be incurred once per set of command line arguments, rather than for each debugger command. The use of dislocate allows the web server to be stateless - a program command sent by the browser can be processed by calling dislocate, sending the command to the command-line-based program, passing the response to the browser, then unhooking from the dislocated process. A short example:

start_ed.cgi (first line needs to have your PATH to expect)
 puts {Content-type: text/html


 log_user 0

 # Add expect to PATH, for use by dislocate

 # Start up ed command that will be contacted by URL
 spawn ./dislocate /bin/ed /etc/inet/hosts

 # Check that dislocate succeeded
 expect {
         "Escape sequence" {}
         default { puts "No output from dislocate?"; exit }

 expect -re ".*" {}

 exp_send "1,3p\r\n"
 expect -re ".+" {} default { puts "no ed output" ; exit }

 # Tell dislocate to disconnect
 #  - send a control-right bracket
 exp_send "\035"

 #  - get dislocate prompt
 expect "1> " {} default { puts "No output from dislocate escape"; exit }

 #  - shut 'er down
 catch { exp_send "q\r" } val

 puts {
 <html> <head> </head>
         <a href="ed.cgi?cmd=1,4p">Have ed print the first four lines</a>


ed.cgi script (modify first line with correct path to expect)
 log_user 0

 puts "Content-type: text/plain\n\n"

 #parray env

 # Add expect to PATH, for use by dislocate
 set env(PATH) "$env(PATH):/PATH/TO/EXPECT"

 spawn ./dislocate

 expect {
         {connect\?} { exp_send "y\r" }
         "enter # or pid:" { exp_send "1\r" }
         default { puts "No ed command available: $expect_out(buffer)\n"; exit }

 expect "Escape sequence is ^]"

 # Get the program command from the web server's query
 set cmd [ string range $env(QUERY_STRING) 4 end ]

 exp_send "$cmd\r"
 expect $cmd
 exec sleep 1
 expect -re {.+} { puts $expect_out(buffer) } default { puts "no output from ed" }

 # Tell dislocate to disconnect
 #  - send a control-right bracket
 exp_send "\035"

 #  - get dislocate prompt
 expect "1> " {} default { puts "No output from dislocate escape"; exit }

 #  - shut 'er down
 exp_send "q\r"

Put start_ed.cgi on a web server. Accessing it via http://webserver/start_ed.cgi will start up /bin/ed on the file /etc/hosts on the web server. After /bin/ed is started, URLs like http://webserver/ed.cgi?cmd=1,10p will run the editor command "1,10p" and the resulting page will contain the output of /bin/ed.

While this trick has limited applications, it's occasionally useful when there's some old program that you'd like to adapt to web use.