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

I am trying to automate an installation of a backup client, the challenge I am facing is the below question will be asked during installation 2 times. "Enter pack name" The first time I need to pass a value "NB_CLT_7.6.0.2" and next time I need to pass a value "q". Every time when I run the script, it is passing a value "NB_CLT_7.6.0.2" both the times and the installation never ends. The below is my code and how to make sure I pass 2 values for the same questions.
use strict; use File::Copy; use Expect; my $timeout = '320'; my $current = qx{pwd}; my $NB = 'NetBackup_7.6.0.1_CLIENTS2.tar.gz'; my $patch = 'NB_CLT_7.6.0.2_Patch.tar'; my $patchtar = `/bin/tar -xf $patch`; chdir("/app"); my $exp = Expect->spawn("./NB_update.install -s"); $exp->expect($timeout, [ qr/Enter pack name \(or q\) \[q\]:\s+/ => sub { $exp->send("NB_CLT_7.6.0.2\r"); exp_continue; } ], [ qr/Do you want to kill all NetBackup daemons\? \[y,n\] \(y\) +\s+/ => sub { $exp->send("\r"); exp_continue; } ], [ qr/Do you want to continue the install\? \[y,n\] \(n\)\s+/ = +> sub { $exp->send("y\r"); exp_continue; } ], [ qr/Enter pack name \(or q\) \[q\]: \(q\)\\s+/ => sub { $exp->send("\r"); exp_continue; } ], [ qr/Do you want to restart all NetBackup daemons\? \[y,n\] \( +y\)\s+/ => sub { $exp->send("\r"); exp_continue; } ], ); $exp->soft_close(); chdir("../");

Replies are listed 'Best First'.
Re: Need help on expect
by hdb (Monsignor) on Feb 20, 2015 at 13:49 UTC

    How about packing the response into a variable and changing it after the first time?

    my $response = "NB_CLT_7.6.0.2\r"; ... ... [ qr/Enter pack name \(or q\) \[q\]:\s+/ => sub { $exp->send($response); $response = "q\r"; exp_continue; } ],

    Admittedly, I have never used Expect so I cannot test whether this would work. Also, this would involve a closure of $response, so I am not sure...

Re: Need help on expect
by Anonymous Monk on Feb 20, 2015 at 13:00 UTC

    If I am understanding your requirement correctly then a quick fix might be this:

    # at the top of your script: my $state = 0; # ... [ qr/Enter pack name \(or q\) \[q\]:\s+/ => sub { if ($state==0) { $exp->send("NB_CLT_7.6.0.2\r"); } else { $exp->send("q\r"); } $state++; exp_continue; } ],

    (untested)

      Oops, I missed you've got a sequence and you expect "Enter pack name" twice. Please disregard the advice in the parent.

        I would think that your proposal will work...

Re: Need help on expect
by Anonymous Monk on Feb 20, 2015 at 13:19 UTC

    One issue for now, there might be more: in this regular expression: qr/Enter pack name \(or q\) \[q\]: \(q\)\\s+/ you've got "\\s+", which matches a literal backslash followed by one or more times the letter "s". I'm guessing you only want to have one backslash there in order to match one or more whitespace characters.

    Otherwise, try setting $exp->exp_internal(1);, $exp->debug(1);, or $exp->debug(2); to see what else might be going wrong.

Re: Need help on expect
by Anonymous Monk on Feb 20, 2015 at 14:43 UTC

    Disclaimer: Without having the actual program to interact with, the following is only based on a simplified test. Also, I assume that the program's prompts are as shown in the regular expressions (with the exception of \s+ instead of \\s+).

    Another problem is that the second "Enter pack name" regex, qr/Enter pack name \(or q\) \[q\]: \(q\)\s+/, will never match, because the first "Enter pack name" regex, qr/Enter pack name \(or q\) \[q\]:\s+/ will always match first. So one possible solution is to move the second regex before the first.

    Or, you could remove the second "Enter pack name" regex, and apply either of the two solutions given above (1, 2), they do seem to work under the assumptions given above.

      Thanks for your replies, I somehow not able to search the below

      Can not install pack when NetBackup daemons are running.

      "<TAB space>" Do you want to kill all NetBackup daemons? y,n (y)

      using the below
      [ qr/Do you want to kill all NetBackup daemons\? \[y,n\] \(y\)\s+/ => +sub { $exp->send("\r"); exp_continue; } ],
      Please let me know if I am searching it wrong.

        Without knowing the output of the program you're working with, this is just a guess, but perhaps your regex doesn't need to be so specific, and something like qr/Do you want to kill all NetBackup daemons\?/ might be enough?

Re: Need help on expect
by toaravind (Initiate) on Feb 25, 2015 at 08:51 UTC
    All, Thanks for all help. It is fixed by following code as suggested.
    my $response = "NB_CLT_7.6.0.2\r"; my $exp = Expect->spawn("./NB_update.install -s"); $exp->expect($timeout, [ qr/Enter pack name \(or q\) \[q\]:\s+/ => sub { $exp->send($response); $response = "q\r"; exp_continue; } ],