A="foo"
B="some other data"
C="appending $A"
D="
some list
with more data
and $B
"
####
#!/bin/bash -
. foo.conf
export A
export B
export C
export D
./foo.pl
####
#!/usr/bin/perl
my %exp_vars = (
A => 'SCALAR',
B => 'SCALAR',
C => 'SCALAR',
D => 'ARRAY',
);
my $env;
foreach my $var (keys %exp_vars)
{
my $type = $exp_vars{$var};
my $val = lc $var;
if (! defined $ENV{$var} or length($ENV{$var}) <= 1)
{
push @out, "# [$var] not exported";
next;
}
if ($type eq 'ARRAY')
{
@{$env->{$val}} = ($ENV{$var} =~ m/(?:\s+)?(\S+)/g);
}
elsif ($type eq 'SCALAR')
{
$env->{$val} = $ENV{$var};
}
}
####
#!/bin/env perl
use strict;
use warnings;
use Data::Dumper;
sub parse_sh
{
my ($data) = @_;
my $r;
$data =~ s/((?: *#.*?)?\n+)/\n/gs; # Remove comment lines
$data =~ s/(\n+)/\n/gs; # Remove blank lines
$data =~ s/ *(\S+)=("?)(.*?)\2 *\n/$r->{lc($1)}="$3"/gse;
return $r;
}
sub parse_sh_maint
{
my ($r, $noset) = @_;
# Interpolate variable names
my $max_passes = 5;
my $not_substituted;
for (1 .. $max_passes )
{
for my $k (keys %$r)
{
next unless (ref(\$r->{$k}) eq 'SCALAR');
$r->{$k} =~ s|\$(\w+)| $r->{lc($1)} // do{ "\$$1" } |ge;
$not_substituted += $r->{$k} =~ tr/$/$/;
}
last unless $not_substituted;
}
# Remove remaining variables and make variables with spaces and newlines arrays
for my $k (keys %$r)
{
$r->{$k} =~ s/\$\S+ *?//gs; # Remove remaining variables
$r->{$k} =~ s/\s+/\n/gs; # Remove leading spaces
if (not grep { $_ eq $k } @$noset)
{
my %dedupe =
map { $_ => 1 }
split(/ |\n/, $r->{$k});
$r->{$k} = ();
@{$r->{$k}} = keys %dedupe;
}
}
return $r;
}
open(my $fh, "<", $ARGV[0]);
my $content = do { local $/ = <$fh> };
my $stuff = parse_sh_maint(parse_sh($content), [qw/scalar1 scalar2/]);
print "Vars: " . Dumper($stuff), "\n";