You are running sqlplus once, before setting environment variables, instead of running it once for each database with the environment variables set.
You are using shell syntax for passing STDIN to sqlplus. This doesn't work in Perl but you can use open and print to achieve a similar result. You can read open and perlipc for more on this.
Maybe something like the following would work better for you:
#!usr/bin/perl -w
use strict;
use warnings;
my $c=`ps -ef |grep -v grep|grep pmon|sed -e 's/.*_//|sort -u >dbname.
+log`;
my $cnt=`ps -ef |grep -v grep|grep pmon|sed -e 's/.*_//|sort -u |awk '
+END {print NR-0}'`;
my $i=1;
while($i<=$cnt) {
my $dbn=`awk 'NR==$i' dbname.log`;
my $dbname = trim($dbn);
my $p=`cat /etc/oratab |grep $dbname|grep -v "#"|gawk -F: {print \
+$2'}`;
$ENV{'ORACLE_SID'}="$dbname";
$ENV{'ORACLE_HOME'}="$p";
open(my $fh, '|-', 'sqlplus "/as sysdba"') or die "$!";
print $fh "select name from v\$database;\nexit;\n";
close($fh);
$i++;
}
exit 0;
sub trim {
my $s = shift;
$s =~s/^\s+|\s+$//g;
return $s;
}
Edit: run sqlplus instead of cat |