Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

System Function...script does not move until process ends.

by curtisb (Monk)
on Apr 05, 2005 at 18:10 UTC ( [id://445068]=perlquestion: print w/replies, xml ) Need Help??

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

Replies are listed 'Best First'.
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.

      Could you give me more of an example of what fork does. I think this what I want to use. I'm trying to set a value back to 0 after the database is started. Once that value is 0 then I want to connect to the database and proceed to unload some tables from it.

      Thanks,

      Bobby

        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";
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
Re: System Function...script does not move until process ends.
by RazorbladeBidet (Friar) on Apr 05, 2005 at 18:13 UTC
    From the first line of system:
    Does exactly the same thing as exec LIST , except that a fork is done first, and the parent process waits for the child process to complete
    If you're starting a database using system - it's going to wait until that child dies!!

    Try starting it in the background (??) or using qx//
    --------------
    "But what of all those sweet words you spoke in private?"
    "Oh that's just what we call pillow talk, baby, that's all."
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.

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

      Though it might "feel" simpler to stick to Perl and use DBI, for the database in question the approach of going out to the system is likely the cleanest, safest and fastest.

      In a nutshell, what he is trying to do is:

      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.

        I see, but then I don't get it why the use of system seems such a problem.
        1. You initiate a new database,
        2. you stop the old one and unload its data,
        3. you reload the data into the new database.
        Seems pretty sequential to me and no need to go into running forks and such.

        Or am I missing a fine point here?

        CountZero

        "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

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).

      dbspawn is a much better solution than the hack I wrote about. Please disregard my "cmd /c start dbeng9" suggestion.

      I usually avoid the command because it is not the appropriate tool for launching the db engine as a daemon (use dbeng9 -ud instead)...however it is designed for exactly the type of situation you are facing.

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 ;-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-04-24 00:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found