in reply to Re^2: Redirect expect screen output to file
in thread Redirect expect screen output to file

I've downloaded and am trying to execute the code. Can you please define ALL missing undefined vars (use bogus names if necessary to disguise sensitive data)?. Thanks.


Update: Please also include your "custom_error" subroutine.

Update2: I'm making a bit of progress, but I believe it would help more if you could describe plainly what you are trying to accomplish with your script. Using Expect is a last resort IMHO--to be used ONLY when human interaction is needed. There may be a better way to handle your problem. For one thing you might check out auditd.

  • Comment on Re^3: Redirect expect screen output to file

Replies are listed 'Best First'.
Re^4: Redirect expect screen output to file
by ryalagikar (Novice) on Oct 12, 2015 at 05:59 UTC


    What i am trying to achieve using expect is, i have to fetch linux command(command may be simple linux command or shell script or perl script etc..) from database and execute the command based on the results have to perform some operations.

    code as below

    #!/usr/bin/perl use strict; use warnings; use Getopt::Long qw(GetOptions); use Expect; use Net::OpenSSH; my $user = ''; #linux login user name my $pswd = ''; # Password my $host = ''; #Host name or machine my $fuser = ''; #functional user or sudo user #Connect to host using OpenSSH my $ssh = Net::OpenSSH->new("$user:$pswd\@$host"); if($ssh->error) { print "Unable to connect $host " . $ssh->error; exit; } my $expect; #sudo su my ( $pty, $pid ) = $ssh->open2pty( { stderr_to_stdout => 1 }, "su +do su - $fuser" ) or die "Failed to attempt sudo su - $fuser"; $expect = Expect->init($pty); $expect->exp_internal(1); $expect->log_file("/tmp/expect.log", "w"); my $before; my $exit1; my $output; my $result = $expect->expect( undef, [ "\[\r\n]?\[^\r\n]+\[%#>\$] \$", sub { my $self = shift; $self->send("ls \r"); } ] ) or custom_error( "Expect Failed "); $expect->hard_close(); exit 0; sub custom_error { my $error = shift; print "Error : $error\n"; #some other operations exit 1; }

    need below output into a file

    Starting EXPECT pattern matching... at /usr/local/share/perl5/ line 597 Expect::expect('Expect=GLOB(0x1b086f0)', undef, 'ARRAY(0x1ae5c +80)') called at ./ line 40 handle id(5): list of patterns: #1: -re `[\r\n]?[^\r\n]+[%#>$] $' handle id(5): Does `' match: pattern #1: -re `[\r\n]?[^\r\n]+[%#>$] $'? No. handle id(5): Does `\033]0;elkuser1@da3p-gen-imn-aut001:~\007\033[?103 +4h[elkuser1@da3p-gen-imn-aut001 ~]$ ' match: pattern #1: -re `[\r\n]?[^\r\n]+[%#>$] $'? YES!! Before match string: `' Match string: `\033]0;elkuser1@da3p-gen-imn-aut001:~\007\033[?1034 +h[elkuser1@da3p-gen-imn-aut001 ~]$ ' After match string: `' Matchlist: () Calling hook CODE(0x1aa89d0)... Sending 'ls \r' to handle id(5) at /usr/local/share/perl5/ line 1421 Expect::print('Expect=GLOB(0x1b086f0)', 'ls \x{d}') called at +./ line 38 main::__ANON__('Expect=GLOB(0x1b086f0)') called at /usr/local/ +share/perl5/ line 825 Expect::_multi_expect(undef, undef, 'ARRAY(0x1616c90)') called + at /usr/local/share/perl5/ line 602 Expect::expect('Expect=GLOB(0x1b086f0)', undef, 'ARRAY(0x1ae5c +80)') called at ./ line 40

    I can redirect this output to file by running the script in back-end(&) mode. Is there any other way i can achieve this(any expect settings).

      If I understand you correctly, I think I can suggest a more reliable solution, but first please answer these questions:

      1. How many local and remote hosts are involved with use of this script?
      2. Are you the only person to use the hosts?
      3. Is the goal to run a command on the remote host and take actions on the remote host with no logging or side effects to be taken on the local host?

      Update: While awaiting your answer, I'll outline my solution which assumes the answer to question three is NO:

      • Write a Perl program on the remote host(s) of interest which does all you need. The program should require the login user name of the remote user if that is required.
      • Ensure all persons needing access to the program and the remote hosts have working access via ssh.
      • If the remote program needs to run as root or other privileged user, either make the script setuid or write a wrapper setuid program which will run the required script. Put the script in each user's home directory to be executed via ssh which will run the setuid program. (If you need multiple user access it would probably be easier to put the one or two programs in a group-owned directory.)

      With the above you can now do something like this on your local host:

      $ ssh user@remotehost progb --arg1=X --arg2=Y

      and all will be taken care of on the remote host. I use such a process to update my remote Apache web server which needs root privileges but which does not allow root access via ssh. I use the setuid wrapper script so I can more easily modify the actual script which does all the work and send it to the remote host as an ordinary user. The setuid program doesn't need updating much so the bother of logging in and acting as root doesn't happen very often after the process is working as desired.

      Note: wherever I have said "setuid" I believe should be "setgid" for multiple users, but I have no experience with that.

Re^4: Redirect expect screen output to file
by ryalagikar (Novice) on Mar 02, 2016 at 11:49 UTC


    'custom_error' subroutine does database update as 'failed' that's it.

    sub custom_error { my $error = shift; my $id = shift; my $end_time = time(); INFO("Error : $error"); INFO("Updating as failed"); # Updating table as failed.. exit 1; }