Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

backtick operator

by spjcr (Initiate)
on May 13, 2010 at 15:16 UTC ( [id://839847]=perlquestion: print w/replies, xml ) Need Help??

spjcr has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I am completely stumped with this one. Any thoughts would be greatly appreciated!

/:perl -v This is perl, v5.8.8 built for x86_64-linux-thread-multi

My script is called from a wrapper script:

} elsif ($stepType eq 'pl') { $rc = system("perl $cwd/bin/$step -config=$configFile"); }

The function in question looks like (i think the issue is around line 247):

sub dbConnect(){ 238 my ($dbName) = @_; 239 my ($dbh,$dbUser,$dbPass); 240 my $tempStr; 241 242 LogStatus "Retrieving $dbName login info"; 243 244 $tempStr = `pwd`; 245 LogStatus "tempStr1: $tempStr"; 246 247 $tempStr = `/prod/scripts/getDBlogin abc01`; 248 LogStatus "tempStr: $tempStr"; 249 #($dbUser,$dbPass) = split(/\s/,`/prod/scripts/getDBlogin "$dbN +ame"`); 250 ($dbUser,$dbPass) = split(/\s/, $tempStr); 251 LogStatus "User for $dbName is $dbUser"; 252 253 die "$0: Could not find password for $dbUser" unless(defined($d +bPass)); 254 255 $dbh = DBI->connect("dbi:DB2:$dbName", $dbUser, $dbPass, {AutoC +ommit=> 0, RaiseError => 1}) 256 || die "Can't connect to $database: $DBI::errstr"; 257 258 LogStatus "Connected to $dbName as $dbUser"; 259 260 return $dbh; 261 }

The getDBlogin script looks like:

1 #!/bin/ksh 2 3 dbname=$1 4 idfl=~/$$.idfl 5 grep -i "$dbname " ~/.passwd > $idfl 6 userid=$(cut -f2 -d" " $idfl) 7 pswrd=$(cut -f3 -d" " $idfl) 8 9 rm $idfl 10 11 print "$userid $pswrd"

The log looks like:

365 [2010-05-12 15:12:13] ============================================ +============= 366 [2010-05-12 15:12:13] Script: create_amb_model 367 [2010-05-12 15:12:13] Process Id: 30199 368 [2010-05-12 15:12:13] Start time: Wed May 12 15:12:13 2010 369 [2010-05-12 15:12:13] ============================================ +============= 370 [2010-05-12 15:12:13] 371 [2010-05-12 15:12:13] DDS AMB Model Creation Starting 372 [2010-05-12 15:12:13] Job name: create_amb_model 373 [2010-05-12 15:12:13] Job config: /jobs/dds/create_amb_model +/config/job.config 374 [2010-05-12 15:12:13] Options: 1 375 [2010-05-12 15:12:13] executing step 1 (dds_prod_pg_load.pl) 376 [2010-05-12 15:12:13] Configuration details: 377 [2010-05-12 15:12:13] Config file: /jobs/dds/create_amb_model +/config/job.config 378 [2010-05-12 15:12:13] Days back: 365 379 [2010-05-12 15:12:13] Database: abc01 380 [2010-05-12 15:12:13] Retrieving abc01 login info 381 [2010-05-12 15:12:13] tempStr1: /jobs/dds/create_amb_model 382 [2010-05-12 15:12:16] Run job has FAILED 383 [2010-05-12 15:12:16] ERROR: 384 [2010-05-12 15:12:16] 385 [2010-05-12 15:12:16] ============================================ +============= 386 [2010-05-12 15:12:16] Process Id: 30199 387 [2010-05-12 15:12:16] End time: Wed May 12 15:12:16 2010 388 [2010-05-12 15:12:16] Elapsed time: 3 seconds 389 [2010-05-12 15:12:16] CPU time: 0.08 seconds 390 [2010-05-12 15:12:16] ============================================ +=============

So I am never seeing the second log entry after line 381 in the log where I would expect to see the output from getDBlogin. When I execute the script from the command line I am seeing the correct output. It appears that something unexpected is happening around line 247 in dbConnect(). At line 382 in the log I Ctrl-C the process - otherwise it would just hang; this kills the forked process which causes the wrapping script to log out 'Run job has FAILED' when it sees a non-zero return code. I am happy to provide more information if needed. Thanks in advance!

Replies are listed 'Best First'.
Re: backtick operator
by JavaFan (Canon) on May 13, 2010 at 15:22 UTC
    When I execute the script from the command line I am seeing the correct output.
    Does this message means it's failing in some other environment? Some environment you're not telling us about? Perhaps a web server? Something else?
    grep -i "$dbname " ~/.passwd > $idfl
    Are you sure this is looking in the right home directory?

      Yes, it looks like it is executing in the right home directory - I am executing the script as the same userid and same environment in both instances.

      The file (.passw) in the home directory looks like this:

      databasename1 username1 password1 databasename2 username2 password2

      ect.

      I should clarify - "When I execute the script from the command line I am seeing the correct output." - I am talking about executing the getDBlogin script here

Re: backtick operator
by AndyZaft (Hermit) on May 13, 2010 at 21:00 UTC
    Any reason you have to use that very awkward ksh script to retrieve 2 text fields from a file? While at first look it should run as you expect it, that construct could be avoided, and by doing it from perl you wouldn't have to rely on result from a backtick operation, that could cause various unforeseen issues due to ENV values and many other problems. I'm thinking here something along the lines of:
    open(DBFILE,"~/.passwd"); while($line = <DBFILE>) { if ($line =~ /$dbname(\w+)(\w+)/) { $dbUser = $1; $dbPass = $2; } }
    If you must have an outside script because it is used from other processes also, you could tidy that one up too with awk for example. The whole writing a temp file to extract a text field is very un-unix way of doing it.
    awk '/^abc01/{ print $2 " " $3; }' ~/.passwd
    would give you the same fields as the getDBlogin script. The strange part about your log is that the log won't even show what came back from your backtick operation, at least you should see
    tempStr:
    by itself.
      Yeah, I thought about that and completely agree with you - I was just reusing that ksh script someone else had written - I replaced that with:
      sub dbConnect(){ my ($dbName) = @_; LogStatus "Retrieving $dbName login info"; my ($dbUser, $dbPass) = get_db_login($dbName); LogStatus "User for $dbName is $dbUser"; die "$0: Could not find password for $dbUser" unless(defined($dbPas +s)); my $dbh = DBI->connect("dbi:DB2:$dbName", $dbUser, $dbPass, {AutoCo +mmit=> 0, RaiseError => 1}) || die "Can't connect to $database: $DBI::errstr"; LogStatus "Connected to $dbName as $dbUser"; return $dbh; } sub get_db_login { my ($dbName) = @_; my ($dbUser, $dbPass, $whoami); chomp($whoami = `whoami`); open(PASSWD,"/home/$whoami/.passwd") or die "~/.passwd does not ex +ist"; while(<PASSWD>){ if($_=~/^$dbName\s+(\w+)\s+(\w+)/i){ $dbUser = $1; $dbPass = $2; } } close PASSWD; return $dbUser, $dbPass; }

      Unfortunately, I am still getting the same behavior as I never see the result of:

      LogStatus "User for $dbName is $dbUser";
        Hmm, but it doesn't die when opening the .passwd file? That's weird, time to debug that get_db_login sub line by line right after the open statement. If for some reason you don't get anything from the file then your while loop would never get executed. Btw, you can use $ENV{USER} instead of `whoami`, one less system call :) I assume it is not dying from
        die "$0: Could not find password for $dbUser" unless(defined($dbPass)) +;
        since the $dbPass will be defined as an empty string at that point, right?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://839847]
Approved by AnomalousMonk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2024-04-18 07:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found