Ohad has asked for the wisdom of the Perl Monks concerning the following question:

Hi

How do I open a xterm from perl script and run a cmd, leaving the xterm for interactive work by a user?

Tried solutions: 1. system call: system("$xt -e '$Setup' &") ; #Didnt work, the xterm closes ($xt = /usr/bin/xterm)

2. my $pid = open2(*Reader, *Writer, "$xt"); print Writer "$Setup\n"; #Didnt work, the $Setup cmd was not executed in the new shell, my guess, it's because it's a new shell.

Any other ideas?

Replies are listed 'Best First'.
Re: Running CMD in perl invoked xterm
by zentara (Cardinal) on Jul 31, 2011 at 16:54 UTC
    You might try forking. This works, but as soon as mc is exited, the spawned xterm closes. Instead of mc, you may be able to write a custom looping program, that accepts input from the xterm, but never ends without a Control c or something. That would be your command processor. Its just a hack, you are almost always better off using an IPC module.
    #!/usr/bin/perl use warnings; use strict; $|++; #You could fork off a child and call exec from that child. #Then you could use the PID from fork to call kill. Thus: my $kidpid; if ( !defined( $kidpid = fork() ) ) { #fork returned undef, so failed die "Cannot fork: $!"; } elsif ( $kidpid == 0 ) { exec("xterm -e mc &"); # xterm stays open until mc is exited # or a custom command processor } # this is all executed in the parent #... print "pid $kidpid\n"; sleep 5; # kill -9, $kidpid; print "hit Enter to exit main script\n"; <>; exit;
    Here is an example of a program you could use as a command processor, for the xterm. It does have one drawback in that it dosn't run your initial $setup command, BUT you could have the command processor run $setup as it's first command to bash, then it would hang around in the while loop for more commands, and the xterm would maintain existence.
    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; use IO::Select; #interface to bash my $pid = open3(\*WRITE, \*READ,\*ERROR,"bash"); #if \*ERROR is false, STDERR is sent to STDOUT my $selread = new IO::Select(); my $selerror = new IO::Select(); $selread->add(\*READ); $selerror->add(\*ERROR); # may not be best use of IO::Select, but it works :-) my($error,$answer)=('',''); while(1){ print "Enter expression for bash, i.e. date\n"; chomp(my $query = <STDIN>); #send query to bash print WRITE "$query\n"; #timing delay needed tp let bash output select(undef,undef,undef,.01); #see which filehandles have output if($selread->can_read(0)){print "ready->read\n"} if($selerror->can_read(0)){print "ready->error\n"} #get any error from bash sysread(ERROR,$error,4096) if $selerror->can_read(0); if($error){print "\e[1;31m ERROR-> $error \e[0m \n"} #get the answer from bash sysread(READ,$answer,4096) if $selread->can_read(0); if($answer){print "$query = $answer\n"} ($error,$answer)=('',''); } waitpid($pid, 1); # It is important to waitpid on your child process, # otherwise zombies could be created.

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: Running CMD in perl invoked xterm
by Anonymous Monk on Jul 31, 2011 at 13:16 UTC
    1. Proc::Background to spawn a shell in the background (say with a specific title)
    2. find its window , say by title, using X11::GUITest FindWindowLike
    3. X11::GUITest function SendKeys to type in the shell
    4. X11::GUITest ... to bring shell to focus
    Probably easier to launch a shellscript with system, which does stuff and opens a shell
      Hi,

      Thanks for your reply, but I need it in my work place, and we dont have here X11 module, and I'm not authurized to install such modules.

      Do you have another good solution?
        Sure, magic. All it requires is a small blood sacrifice... :|