———package
Shell::Var::Reader;
use
5.006;
use
strict;
use
warnings;
=head1 NAME
Shell::Var::Reader - Runs a sh or bash script and returns the variables that have been set as well as their values.
=head1 VERSION
Version 0.6.0
=cut
our
$VERSION
=
'0.6.0'
;
=head1 SYNOPSIS
Lets say '/usr/local/etc/someconfig.conf' which is basically a shell
config and read via include in a sh or bash script, this can be used for
getting a hash ref conttaining them.
Similarly on systems like FreeBSD, this is also useful for reading '/etc/rc.conf'.
use Shell::Var::Reader;
use Data::Dumper;
my $found_vars=Shell::Var::Reader->read_in('/usr/local/etc/someconfig.conf');
print Dumper($found_vars);
=head1 SUBROUTINES
=head2 read_in
This runs a specified file as a include and then figures out what the
new variables are. fetching them.
=cut
sub
read_in {
my
$file
=
$_
[1];
if
( !
defined
(
$file
) ) {
die
(
'No file specified'
);
}
if
( !-f
$file
) {
die
(
'"'
.
$file
.
'" does not exist or is not a file'
);
}
# figure out if we are using bash or not
my
$raw_file
= read_file(
$file
) or
die
'Failed to read "'
.
$file
.
'"'
;
my
@raw_split
=
split
( /\n/,
$raw_file
);
my
$shell
=
'sh'
;
if
(
defined
(
$raw_split
[0] ) && (
$raw_split
[0] =~ /^\
#\!.*bash/ ) ) {
$shell
=
'bash'
;
}
#
# figure out what variables already exist...
#
my
$cmd
=
$shell
.
" -c 'if [ -z \"\$BASH_VERSION\" ]; then set; else set -o posix; set; fi'"
;
my
$results
= `
$cmd
`;
my
$base_vars
= {
'ShellVarReaderFile'
=>1};
my
@results_split
=
split
( /\n/,
$results
);
foreach
my
$line
(
@results_split
) {
if
(
$line
=~ /^[\_a-zA-Z]+[\_a-zA-Z0-9]*\=/ ) {
my
@line_split
=
split
( /=/,
$line
, 2 );
$base_vars
->{
$line_split
[0] } = 1;
}
}
#
# Figure out what has been set
#
$ENV
{ShellVarReaderFile} =
$file
;
$cmd
=
$shell
.
" -c ' . \"\$ShellVarReaderFile\" > /dev/null 2> /dev/null ; if [ -z \"\$BASH_VERSION\" ]; then set; else set -o posix; set; fi'"
;
$results
= `
$cmd
`;
my
$found_vars
= {};
@results_split
=
split
( /\n/,
$results
);
my
$multiline
= 0;
my
$var_key
;
foreach
my
$line
(
@results_split
) {
if
(
$line
=~ /^[\_a-zA-Z]+[\_a-zA-Z0-9]*\=/ && !
$multiline
) {
my
@line_split
=
split
( /=/,
$line
, 2 );
$var_key
=
$line_split
[0];
$found_vars
->{
$var_key
} =
$line_split
[1];
# if the value starts with a ' and does not end with a '
# it is going to be multiline
if
(
$found_vars
->{
$var_key
} =~ /^\'/
&&
$found_vars
->{
$var_key
} !~ /\'$/ )
{
$found_vars
->{
$var_key
} =~ s/^\'//;
$multiline
= 1;
}
else
{
$found_vars
->{
$var_key
} =~ s/^\'//;
$found_vars
->{
$var_key
} =~ s/\'$//;
}
}
else
{
$found_vars
->{
$var_key
} =
$line
;
# if it ends with ', then we have reached the end of the variable
if
(
$found_vars
->{
$var_key
} =~ /\'$/ ) {
$found_vars
->{
$var_key
} =~ s/\'$//;
$multiline
= 0;
}
}
}
#
# remove base vars
#
my
@found_keys
=
keys
(%{
$found_vars
});
foreach
my
$var_key
(
@found_keys
) {
if
(
defined
(
$base_vars
->{
$var_key
})) {
delete
$found_vars
->{
$var_key
};
}
}
return
$found_vars
;
}
=head1 AUTHOR
Zane C. Bowers-Hadley, C<< <vvelox at vvelox.net> >>
=head1 BUGS
Please report any bugs or feature requests to C<bug-shell-var-reader at rt.cpan.org>, or through
the web interface at L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Shell-Var-Reader>. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Shell::Var::Reader
You can also look for information at:
=over 4
=item * RT: CPAN's request tracker (report bugs here)
=item * Search CPAN
=back
=head1 ACKNOWLEDGEMENTS
=head1 LICENSE AND COPYRIGHT
This software is Copyright (c) 2023 by Zane C. Bowers-Hadley.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
=cut
1;
# End of Shell::Var::Reader