-   Programming (
-   -   Perl: Wait for ssh connection to close (

kenneho 10-28-2005 08:34 AM

Perl: Wait for ssh connection to close
I'm trying to get my perl script to execute a command (using ssh) on a remote computer, and keep the connection open until the job is finished.

To illustrate, say I execute the following code:


foreach $machine (@machines) {
              system("xterm -e ssh $machine 'emacs' &");   

My intention is that I execute emacs on the remote machines, but not closing the connection until I exit emacs. I want one xterm pr machine executing the program, and the xterm should exit when the remote programs exit.

As of now, emacs is executed, but the connection is closed as soon as the command is issued on the remote program. Is want the connection to stay open until the actual application closes.

How can this be accomplised?

Quigi 10-28-2005 09:27 AM

Re: Perl: Wait for ssh connection to close
The ampersand (bold below) puts the job in the background:

system("xterm -e ssh $machine 'emacs' &");
And that's why system returns right away. You should leave it out. It's much like what you get when typing the command yourself in a shell. Compare these two:

xterm &

The first runs the terminal in the background, and you get the prompt back right away. The second waits till the xterm completes.

Maybe you want to elaborate on what you intend to happen.

kenneho 10-28-2005 10:19 AM

I added the "&" on purpose so that the xterm would run in the background. My fist post was not very precise, so let my try again. :)

My aim is to automate this:
1) log onto the remote machines (using ssh) in xterms, one xterm pr machine/connection
2) run a program (for example emacs)
3) when the program exits, close the ssh connection and exit the script

In essence: How do I open, say, 3 xterms at once, each having logged onto a different machine, and the xterms run a remote program (i.e. emacs) and are not closed until the program has finished?

Did this make it more clear?

Quigi 10-28-2005 01:03 PM

Still more questions: Why do you use xterm? Does ssh require a password? Do you tunnel X11, or should emacs run in the xterm, like "emacs -nw"?
Do you need the perl script to wait till all emacses and their xterms exit?

One answer: ssh -t

Quigi 10-28-2005 01:26 PM

The following will open all windows (and exit).

my @machines = qw(a b c);
foreach my $machine (@machines) {
  system "xterm -e ssh -t -x $machine emacs &";

Then you can talk to ssh in each window if necessary (confirm, password) after which emacs runs. When you type C-x C-c, exacs exits, then the remote shell, the ssh connection, and finally xterm.

I'm aware that that violates your aim

3) when the program exits, close the ssh connection and exit the script
I think it's possible to achieve, if it's important to you.

kenneho 10-29-2005 04:44 AM

I'm using ssh-keys to authenticate my machine to the remote machines. These machines doen't have X installed, as they as just "slaves" which are to run a distributed program. I use xterm so that I can have one ssh connection pr xterm window, and communicate with these machines through the terminals. Is there another, better way of doing this?

The perl script need not wait till the xterms exit, as long as these xterms maintains the ssh-connection. I thought the xterms would exit automatically
when the script ended, but I guess I was wrong. So never mind that last aim. :)

I'll try the "-t" option and see if it help. Thanks for the help so far!

david_ross 10-29-2005 08:03 AM

Why not fork for each machine and then waitpid in the main script after your loop.

kenneho 10-29-2005 08:36 AM

I thought about it, but as this script is my very first perl-script I don't know how to do it + I figured I'd try without forking.
Could you provide me a link to some example code for forking in perl?

david_ross 10-29-2005 09:03 AM

You should just need to use:

foreach $machine (@machines){
  my $pid=fork(); # Perform the fork
  next if($pid); # Next machine if we are the parent
  system("xterm -e ssh $machine 'emacs'");
  exit; # Exit the child
# Wait for child processes to complete
use POSIX ":sys_wait_h";
do {
 $kid = waitpid(-1,&WNOHANG);
} until $kid == -1;

There are lots of examples and documentation out there:

kenneho 10-29-2005 09:19 AM

Okay, thanks! I'll check it out!

All times are GMT -5. The time now is 01:09 PM.