HACKER Nora wrote:
Hello,
Hello,
I would be really glad if someone could give me a hint to my following problem: I have a script that runs smoothly on AIX5.3, installed Perl is 5.8.8. Now I need it to run on AIX6.1, Perl is 5.8.8 as well, but I experience a strange, differing behaviour. I have a sub-function that greps for a certain process in the ps list. In the course of this script this function is called twice. On AIX5.3, I get the same result (process running or not) both times, on AIX6.1 I get "process running" at the first call of the sub, but error -1 at the second call. Could this be an OS behaviour problem? Here are the code snippets: ################# # This is the main function of my script (doing DB backups/restore) sub backup { #[... some other subs ...] appl( 'start', 'D', checkStatus('D') ); # starts the Oracle DB if checkStatus returns that DB is not running; gives correct result #[... some other subs ...] my $dbvers = getDBVersion(); # gets the application version from the DB; on AIX6.1 this produces os level error -1 #[... some other subs ...] } ################# # This is the sub-function for getting the application version from the DB sub getDBVersion { my $fnc = ( caller 0 )[$CALLER_ID];
Where did $CALLER_ID come from?
DEBUG("$fnc - DBType: $dbtype\n");
Where did $dbtype come from?
my $vdb = $empty; my $adb = $empty;
Where did $empty come from? What is $empty supposed to contain?
if ( $dbtype eq 'V' ) { # in my case FALSE, ignore # viaMG-DB temporär umspeichern, um Version aus ApplDB ermitteln zu können $vdb = $db; DEBUG("$fnc - viaMG-DB: $vdb\n"); print 'Bitte zugehörige Applikations-DB angeben: '; INFO("$fnc - Bitte zugehörige Applikations-DB angeben: "); $adb =<STDIN>; chomp $adb; $db = $adb;
Shouldn't that be: my $db = $adb;
INFO("$fnc - DB: $db\n"); # SID setzen $ENV{'ORACLE_SID'} = "$db";
Why are you copying $db to a string?
INFO("$fnc - ORACLE_SID: $ENV{'ORACLE_SID'}\n"); } my $status = checkStatus('D'); #<-- this FAILS at the second execution :-( DEBUG("$fnc - DBStatus aus Unterfunktion checkStatus: $status\n"); my $dbvers; if ( $status == 0 ) { my $dbverslst = "$tmps/dbversion_$db.lst"; DEBUG("$fnc - Tempfile mit DB-Version: $dbverslst\n"); system "$sqlplus" . ' "/as sysdba" ' . "\@$sqls/get_db_version.sql $db> /dev/null 2>&1";
You should verify that system() executed correctly. perldoc -f system
DEBUG( "$fnc - $sqlplus \"/as sysdba\" \@$sqls/get_db_version.sql $db\n"); if ( fgrep { /ERROR/ } $dbverslst ) {
The UNIX fgrep utility does not use regular expressions so this is a bit confusing. Why aren't you just using perl's built-in grep() here? And why use grep() at all on a list with only one element?
if ( $dbverslst =~ /ERROR/ ) {
$dbvers = giveDBVersion(); } else { DEBUG("$fnc - Kein Error aus get_db_version.sql.\n"); } my @dbversgrep; my $fh_dbverslst = IO::File->new("< $dbverslst");
You should *always* verify that files opened correctly. Why aren't you just using perl's built-in open() here?
open my $fh_dbverslst, '<', $dbverslst or die "Cannot open '$dbverslst' because: $!";
if ( ! $fh_dbverslst ) {
That is not the correct way to test a filehandle. perldoc -f fileno Or just test the return value of open(). perldoc perlopentut perldoc -f open
LOGDIE("$fnc - $dbverslst konnte nicht gelesen werden!\n"); } while (<$fh_dbverslst>) { chomp; $_ =~ s/ //g;
Why "$_ =~" here and not below?
if (/[\d.]/s) { push @dbversgrep, $_ }
The /s option only affects the . special character which you are not using.
} undef $fh_dbverslst; $dbvers = $dbversgrep[0]; INFO("$fnc - Datenbank-Version (aus DB): $dbvers\n"); if ( -e "$dbverslst" ) {
Why are you copying $dbverslst to a string? Why test for (-e) existence when unlink(), through $!, will tell you if $dbverslst doesn't exist?
unlink $dbverslst or INFO( "$fnc - Datei $dbverslst konnte nicht gelöscht werden: $!\n"); } } else { INFO( "$fnc - Datenbank $db ist down.\n" ); print "Datenbank $db ist down.\n"; $dbvers = giveDBVersion(); } if ( $dbtype eq 'V' ) { $db = $vdb; # viaMG-DB wieder als Haupt-DB einsetzen # SID setzen $ENV{'ORACLE_SID'} = "$db";
Why are you copying $db to a string?
INFO("$fnc - ORACLE_SID: $ENV{'ORACLE_SID'}\n"); } return $dbvers; } ################# # This is the sub-function for checking whether the Oracle DB (and/or Tuxedo) is running sub checkStatus { my ( $art ) = @_; my $fnc = ( caller 0 )[$CALLER_ID];
Where did $CALLER_ID come from?
DEBUG("$fnc - Übergabeparameter: @_\n"); my $status; if ( $art eq 'D' ) { system "ps -ef |grep -v grep |grep dbw |grep -q $db";
Where did $db come from?
my $test = `ps -ef |grep -v grep |grep dbw |grep $db`; # print grepped ps list for debugging print "Test: $test\n"; $status = $?>> $SHIFT_ERROR;
Where did $SHIFT_ERROR come from? You should put this line *directly* *after* the line that sets $?. You are probably getting the status from the shell that the back-ticks run, but print() might affect its value. If you want the status from system() you should only use $? right after system() has completed.
When you use system() you should verify that it executed correctly. perldoc -f system
if ( $status == 0 ) { INFO("$fnc - DB-Status: $status = DB $db is running\n"); } else { INFO("$fnc - DB-Status: $status = DB $db is not running\n"); } } elsif ( $art eq 'T' ) { system "ps -ef |grep -v grep |grep -w BBL |grep -wq $tux";
Where did $tux come from?
$status = $?>> $SHIFT_ERROR; if ( $status == 0 ) { INFO("$fnc - Tuxedo-Status: $status = Tuxedo $tux is running\n"); } else { INFO("$fnc - Tuxedo-Status: $status = Tuxedo $tux is not running\n"); } } return $status; } ################# # This is the script output with the grepped ps list output for debugging purposes: oracle:/opt/magna/wartung> dbmove.pl -m s -d MVRSTDB Default-Tuxedo: mvrst Return code: 0 Test: oracle 299118 1 0 08:57:47 - 0:00 ora_dbw1_MVRSTDB oracle 765990 1 0 08:57:47 - 0:00 ora_dbw0_MVRSTDB DB MVRSTDB is running Return code: -1 Test: oracle 299118 1 0 08:57:47 - 0:00 ora_dbw1_MVRSTDB oracle 765990 1 0 08:57:47 - 0:00 ora_dbw0_MVRSTDB DB MVRSTDB is not running [...] Any hints in which direction to investigate???
Do you have utilities like pgrep on AIX? Does your version of ps support the -o option?
In some shells, instead of doing: ps -ef | grep -v grep | grep dbw You can just do: ps -ef | grep d[b]w John -- Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction. -- Albert Einstein -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/