That will work, yes, but I'd be a bit worried about the security implications. What happens if someone (accidentally or maliciously) inserts a command like "rm -rf ~" into the config file?
If you have a fixed set of allowable commands, then set up a dispatch table and use that to determine which command to invoke rather than passing external input directly to the shell:
CODE
my %dispatch = (
cmd1 => \&sub1,
cmd2 => \&sub2,
);
&{$dispatch{$HR_config->{CMD_cp}}}(@parameters);
sub sub1 {
# process cmd1
}
sub sub2 {
# process cmd2
}
If you don't have a fixed set of allowable commands, then consider whether you might at least be able to examine the entered commands for safety/sanity before executing them. Turning on taint mode (by adding a "-T" to your "#!/usr/bin/perl" line at the top of the program) will help to enforce this by refusing to let you give parameters to system() without passing them through a regex first and passing only the matches:
CODE
#!/usr/bin/perl -T
# You have to clean out %ENV if you're going to call external
# commands while running under taint mode so that malicious
# environment settings can't compromise your security
%ENV = (
PATH => '/bin:/usr/bin',
);
my $cmd = <STDIN>;
eval {
system($cmd); # Fails because $cmd is tainted
};
if ($@) {
print "system(\$cmd) died:\n$@---\n";
}
# Only match an date, less, ls, more, or pwd command, plus
# possible arguments parameters, but not a second command
# on the same line
if ($cmd =~ /(date|less|ls|more|pwd)\b\s*([^;&<>]*)/) {
# Because $1 and $2 contain regex matches, they are no
# longer tainted
system("$1 $2");
}