I wrote about the topic of running external commands at length here. In this case, since you seem to want to pass something to the script's STDIN and get something from its STDOUT, IPC::Run3 is a good choice IMO; it allows you to capture STDERR too if you need to. Note that running the script with a relative path ("./shellscript.sh") is another possible point of failure, as it relies on the current working directory.
use warnings;
use strict;
use IPC::Run3 'run3';
my $in = " string argument passed ";
my @cmd = ('/path/to/shellscript.sh');
run3 \@cmd, \$in, \my @out or die "run3 failed";
$?==0 or die "command failed, \$?=$?";
chomp(@out);
print "<<$_>>\n" for @out;
Update: Changed output to array to be more in line with OP's code.