curtisb has asked for the wisdom of the Perl Monks concerning the following question:
All,
Once again I am back to my old tricks. I'm working on a database rebuild script that will shutdown the old database, create a new database file, start the old database as an engine only, then unload the old database and reload into the new database.
My problem is where I have noted. Once the old database is started it will not move to the next line of code until the database is stopped. So, my question is this:
How do I get the script to move to the next line of code? Is there something I'm missing when I use the "system" fucntion?
Any help would be greatly appreciated.
Thanks,
Bobby Curtis
#!/usr/bin/perl -w
use strict;
#########################
# #
#DEFINE GLOBAL VARIABLES#
# #
#########################
#my @args = ("-c \"dsn=dba_fmds;uid=dba;pwd=sql\"","-ii","-t plan","D:
+/workingfiles/scripts");
my @args0 = ("\/FI \"imagename eq dbsrv9.exe\"");
my @stopargs = ("stop ASANYs_awrdsprodcution");
my @scqueryargs = ("query ASANYs_awrdsprodcution");
my @initargs = ("-p 8192","D:/WorkingFiles/DATABASES/CURRENTDATABASES/
+ARNET/TestBuild/"."arsams.db");
my @engstartargs = ("D:/WorkingFiles/DATABASES/CURRENTDATABASES/ARNET/
+arsams.db");
my $stopvalue = 0;
#########################
# #
#Function Script #
# #
#########################
if (system("tasklist",@args0) == 0 && system("sc @scqueryargs") == 0)
{
print "\n";
print "Stop service: ";
my $std_in0 = <STDIN>;
chomp($std_in0);
if($std_in0 eq "y"){
system("sc @stopargs");
$stopvalue = 1;
print "\n";
print "Stop value set to: $stopvalue\n";
print "\n";
if($stopvalue == 1)
{
print "Creating new database file with 8192 kilobyte page
+file\n";
print "\n";
system("dbinit", @initargs);
print "\nNew database file created\n";
print "Starting old database with dbeng9\n";
system("dbeng9", @engstartargs); #HANGS UNTIL DATABASE IS
+ SHUTDOWN....WHY????
print "Old database started with dbeng9\n";
$stopvalue = 0;
}
}else{
warn "Service will not be stopped\n";
}
}else{
print "==>==>==> failure, exit status = $?\n";
}
Janitored by Arunbear - added readmore tags, as per Monastery guidelines
Re: System Function...script does not move until process ends.
by Mugatu (Monk) on Apr 05, 2005 at 18:13 UTC
|
system does not return until the program you called returns. That is the documented behavior. You can use system("foo &") as a quick-hack way to put the process into the background. Other options are fork and exec manually, or a piping form of open. | [reply] [d/l] |
|
| [reply] |
|
| [reply] |
|
|
|
|
Is the code you pasted a simplified sample of the original? If not, I do not understand why you have the whole $stopvalue business in the first place. Your code progresses linearly, and the if ($stopvalue == 1) condition is pointless. At that point, $stopvalue is always set to 1.
Putting that point aside, unless you already know what fork and exec do, it would probably be best to avoid them. They are the low level primitives, and the other available methods are usually simpler and more convenient. Doing the fork/exec yourself should be reserved for times when you really need it.
In your case, I would lean toward a piping open, as it will provide enough control but also enough simplicity. As an added bonus, you'd be able to read the program's output, if necessary. Here's an example:
my $pid = open my $lsfh, "-|", "sleep", 10
or die "Cannot exec sleep: $!\n";
print "'sleep' is running in the background.\n";
print "The background process has a PID of $pid.\n";
waitpid $pid, 0;
print "All done.\n";
| [reply] [d/l] [select] |
Re: System Function...script does not move until process ends.
by JamesNC (Chaplain) on Apr 06, 2005 at 02:48 UTC
|
I believe this is what you are looking for. Putting a 1 as the first arguement tells system to not wait. tye posted this gem some time ago.
system(1,dbeng9,@engstartargs ); # don't wait for return
JamesNC | [reply] [d/l] |
Re: System Function...script does not move until process ends.
by RazorbladeBidet (Friar) on Apr 05, 2005 at 18:13 UTC
|
| [reply] |
Re: System Function...script does not move until process ends.
by graff (Chancellor) on Apr 06, 2005 at 01:08 UTC
|
Shucks. Looks like your on a windows system. If you were using unix, you could just include a "&" at the end of the command line that you pass to system(), and the shell invoked by system() to run the command would do the fork/exec for you.
(Maybe if you have a windows port of the bash shell, you'd have the same functionality regarding "background job control" as you get on unix -- I'm not a windows user these days, so I'm not sure about that.)
OTOH, doing the fork/exec yourself with perl functions will give you a lot more control over the situation, and you'll probably want that. | [reply] |
Re: System Function...script does not move until process ends.
by CountZero (Bishop) on Apr 06, 2005 at 06:40 UTC
|
Is there a DBI/DBD-module for your database? If so, it is perhaps easier to connect to the database using DBI, extract the data you need and put them into a new database again using DBI.
CountZero "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
| [reply] |
|
dbinit my_new_db.db
dbunload my_old_db <<- this creates a file called "reload.sql"
dbisql my_new_db.db read reload.sql
throw in some error checking (exit codes, file/directory exists, etc...) and you've got a great rebuild/upgrade mechanism.
I've done exactly this in Perl, Bash/Sh, and .CMD/.BAT.
| [reply] [d/l] |
|
| [reply] [d/l] |
|
|
Re: System Function...script does not move until process ends.
by data64 (Chaplain) on Apr 06, 2005 at 18:38 UTC
|
Instead of just calling dbeng9, call dbspawn. Its meant for starting the database in the background and is cross platform (ie. there are versions for all platforms that the database runs on).
| [reply] |
|
| [reply] |
Re: System Function...script does not move until process ends.
by mobiGeek (Beadle) on Apr 06, 2005 at 18:44 UTC
|
As others have pointed out, the problem is in your use of system().
I believe, though I don't have time to confirm, that you could do the following:
system("cmd /c start dbeng9", @engstartargs); # SHOULDN'T HANG NOW
Though, of course, this is a win32-specific solution. The fork() solutions suggested by others would be more cross-platform (though with the hard-coded path names does it really matter?)
BTW: the sqlanywhere newsgroups are always available ;-) | [reply] [d/l] |
|
|