0

I have a bash script which contains the only content (an array ) e.g

bash_arrray.sh

locDbList=(default default_test)

I need to use this array in a Perl script.

Is it possible to load the array definition from bash file into Perl in some way?

If not then how I can define a Perl file with the same array and load that in a second Perl script?

In second case :

perl_arrray.pl

second_perl_file.sh ( load the perl_array in here ). 

The last option is to put the array information in a format which I can read from both Perl and bash, e.g an ini file

5
  • 2
    I have a feeling you've got an XY Problem. Why do you want two Perl scripts? What are you really trying to do? Why can't you code everything in one Perl script? One Bash script? Commented Jan 17, 2013 at 15:49
  • I have a bash script that builds a package and puts the user param in a bash into file (in the form of array) .Later on during package installation ( perl based).I want to use those values in perl , thanks Commented Jan 17, 2013 at 15:50
  • @JonathanLeffler what do you suggest how to store config data which is accessible easly from both perl and bash , thanks Commented Jan 17, 2013 at 15:54
  • @sakhunzai, can you show some example content of the bash file? Commented Jan 17, 2013 at 16:00
  • @dan1111 bash has an array simply: locDbList=(default default_test) Commented Jan 17, 2013 at 16:25

1 Answer 1

1

You can't see it from %ENV and event if you run declare -a in perl, it still won't pull the arrays defined in the immediate outer scope.

You might have to work both ends for this. And it's not that easy, but here's a start.

Passing to Perl

  • First, I created a bash function to ready this value to be passed.

    function pass_array
    {
        # get the array name 
        declare array_name=$1;
        # get all declarations for defined arrays.
        # capture the line that corresponds with the array name
        declare declaration=$(declare -a | grep --perl-regex --ignore-case "\\b$array_name\\b");
        # - At this point this should look like:
        #   declare -a* array_name='([0]="value1", [1]="value2", [2]="value3")'
        # - Next, we strip away everything until the '=', leaving:
        #   '([0]="value1", [1]="value2", [2]="value3")'
        echo ${declaration#*=}; 
    }
    
  • You could pass it to perl like so:

    perl -Mstrict -Mwarnings -M5.014 -MData::Dumper -e 'say Data::Dumper->Dump( [ \@ARGV ], [ q[*ARGV] ] )' "$(pass_array locDbList)"
    
  • On the Perl side, you might have a convenience function like this:

    sub array_from_bash {
        return shift =~ m/\[\d+\]="([^"]*)"/g;
    }
    

Named Array

Of course, you could want to retain the name of the array, to allow passing more than one, or locating it dynamically, say with other environment variables. (export DB_LIST_NAME=locDBList)

In that case, you might want to change what the pass_array bash function echoes.

 echo echo ${declaration#*-a[b-z]* };

And might want to have a Perl function like this:

sub named_array_from_bash {
    return unless my $array_name = ( shift // $_ );
    my $arr_ref = [ @_ ? @_ : @ARGV ];
    return unless @$arr_ref 
               or my ( $array_decl ) = 
                    grep { index( $_, "$array_name='(" ) == 0 } @$arr_ref
                    ;
    return array_from_bash( substr( $array_decl, length( $array_name ) + 1 ));
}

Environment Variable

Yet, another idea is simply export a variable with the same information:

declare decl=$(declare -a | grep --perl-regex --ignore-case "\\b$array_name\\b");
export PERL_FROM_BASH_LIST1=${decl#*-a[a-z]* };

And read that from Perl.

my @array = array_from_bash( $ENV{PERL_FROM_BASH_LIST1} );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.