Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

External programs

by clrobert (Initiate)
on Jul 20, 2000 at 19:30 UTC ( [id://23398]=perlquestion: print w/replies, xml ) Need Help??

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

As a novice, I'm calling an external program from a script. The ext. pgm. needs to run externally, not within a shell. I've tried both 'system' and 'exec', passing arguments, but nothing works. Seems like a simple concept, obviously I'm missing something. Thanks.......

Replies are listed 'Best First'.
Re: External programs
by tye (Sage) on Jul 20, 2000 at 19:47 UTC

    Trying to guess what you meant, I think you are complaining that the script waits for the program to finish before continuing to the code after system. I think the undocumented (at least until recently) incantation

    system( 1, "command that you want to run" );
    will prevent the script from waiting (I know it will under OS/2 and Win32, but I think that it has been ported to the majority of Perl platforms). Other solutions were specific to the type of operating system you were using.

    ...but I'm not sure that this is what you meant. Could you be more... specific? Some sample lines of code is often a big help. Also, "doesn't work" is never a good description of a failure. Do you get an error message? What did you expect that didn't happen? What happened that you didn't expect?

Re: External programs
by cleen (Pilgrim) on Jul 20, 2000 at 19:34 UTC
    have you tried open(FILE, "/full/path/to/program|"); ? or in any of the cases have you tried acctually putting the full path to the program in question? More information would be really usefull, IE: why the system and exec stuff "doesnt work"
RE: External programs
by JanneVee (Friar) on Jul 20, 2000 at 19:43 UTC
    I usually use backticks to execute external programs and retrieve the output from them...

    e.g.

    $file = "test.txt"; $ext_out = `ls -l $file`; print "$ext_out";
Re: External programs
by cwest (Friar) on Jul 20, 2000 at 19:57 UTC
    I hope what you're really asking is I don't want my second Perl program to run in a new process and you just don't know it.

    But, as cleen writes, you aren't being very clear.

    This will help you if your question is what I think it is. (you can ignore the $\ assignments, that's me testing lazily :)

    $\="\n"; print $$; if ( open PROG, '/home/userxyz/prog.pl' ) { undef $/; eval <PROG>; warn $@ if $@; close PROG or die $!; } print $$;
    and PROG looks like this:
    #!/usr/bin/perl -w use strict; $|++; $\="\n"; print $$;
    If your question doen't involve the second program being Perl, then my example won't work... but I can't think of how to do it without starting a new process... I haven't had my coffee either.

    Enjoy!

    --
    Casey
    
Re: External programs
by JP Sama (Hermit) on Jul 21, 2000 at 04:01 UTC
    As another newbbie, the only solution I can give is:

    What if you run in serverA a testa.pl, that runs another program : testb.pl in serverB, and with the testb.pl, you could run locally your batch (test.bat) file.

    I know this SUX... but i think it would work!

    (please Wise monks : kill me if i gave a nonsense reply... so i can learn something with my errors!)

    #!/jpsama/bin/perl -w $tks = `mount`; $jpsama = $! if $!; print $jpsama;
Re: External programs
by clrobert (Initiate) on Jul 20, 2000 at 22:22 UTC
    Sorry folks, I guess I could have been more vague if I had tried. The code: $program = "\\\\serverB\\directory\$\\test1.bat"; system($program, arg1, arg2); The situation is this: in an NT network I am running a Perl script on server A. From there, I am calling a program on server B, which needs to run on server B. When I run the program from NT Explorer, it writes to local files. When I call it from server A using Perl, it is running in a shell on server A; the program runs, but it doesn't see the 'local' (to the called program on system B) files it needs to write to. So when I run the script, I get "The system cannot find the path specified." messages anytime the called program tries to write to a file. Thanks again.......

      To cause a program to run on another server, you'd need a protocol for doing that. Under NT, "Remote Cmd" (aka "RCmd") from the resource kit is not bad (rlogin and rsh from the resource kit are not good). If you installed the service on serverB, the service was running, you have rcmd.exe on serverA, and you are properly authenticated to serverB, then you could use:

      rcmd \\serverb path\test1.bat
      But I won't go into this further because I don't think that is the best solution in this particular case.

      When you run a program from Explorer, it usually runs the program with its default directory set to the directory where Explorer found the program. It sounds like just setting the default directory before running the program may fix your problem.

      Now, you can't chdir('//serverB/directory$') because non-kernel processes on NT need a drive letter for their current directory. So you need to map a drive letter to that directory and chdir to the root directory of that drive. Win32::NetResource will let you map and unmap the drive letter.

      I don't have Win32::NetResource examples handy or memorized so here is a non-Perl solution:

      pushd \\serverB\directory$ test1.bat popd

        For the greater good:
        NAME Win32::NetResource - manage network resources in perl SYNOPSIS use Win32::NetResource; $ShareInfo = { 'path' => "C:\\MyShareDir", 'netname' => "MyShare", 'remark' => "It is good to share", 'passwd' => "", 'current-users' =>0, 'permissions' => 0, 'maxusers' => -1, 'type' => 0, }; Win32::NetResource::NetShareAdd( $ShareInfo,$parm ) or die "unable to add share"; DESCRIPTION This module offers control over the network resources of Win32.Dis +ks, printers etc can be shared over a network. DATA TYPES There are two main data types required to control network resource +s. In Perl these are represented by hash types. %NETRESOURCE KEY VALUE 'Scope' => Scope of an Enumeration RESOURCE_CONNECTED, RESOURCE_GLOBALNET, RESOURCE_REMEMBERED. 'Type' => The type of resource to Enum RESOURCETYPE_ANY All reso +urces RESOURCETYPE_DISK Disk re +sources RESOURCETYPE_PRINT Print +resources 'DisplayType' => The way the resource should +be displayed. RESOURCEDISPLAYTYPE_DOMAIN + The object should be display +ed as a domain. RESOURCEDISPLAYTYPE_GENERIC + The method used to display t +he object does not matter. RESOURCEDISPLAYTYPE_SERVER + The object should be display +ed as a server. RESOURCEDISPLAYTYPE_SHARE + The object should be display +ed as a sharepoint. 'Usage' => Specifies the Resources usag +e: RESOURCEUSAGE_CONNECTABLE RESOURCEUSAGE_CONTAINER. 'LocalName' => Name of the local device the + resource is connected to. 'RemoteName' => The network name of the reso +urce. 'Comment' => A string comment. 'Provider' => Name of the provider of the +resource. %SHARE_INFO This hash represents the SHARE_INFO_502 struct. KEY VALUE 'netname' => Name of the share. 'type' => type of share. 'remark' => A string comment. 'permissions' => Permissions value 'maxusers' => the max # of users. 'current-users' => the current # of users. 'path' => The path of the share. 'passwd' => A password if one is req' +d FUNCTIONS NOTE All of the functions return FALSE (0) if they fail. GetSharedResources(\@Resources,dwType) Creates a list in @Resources of %NETRESOURCE hash refere +nces. The return value indicates whether there was an error in accessing any of the shared resources. All the shared resources that were encountered (until the point of an e +rror, if any) are pushed into @Resources as references to %NETRESOURCE hashes. See example below. AddConnection(\%NETRESOURCE,$Password,$UserName,$Connection) Makes a connection to a network resource specified by %NETRESOURCE CancelConnection($Name,$Connection,$Force) Cancels a connection to a network resource connected to +local device $name.$Connection is either 1 - persistent connec +tion or 0, non-persistent. WNetGetLastError($ErrorCode,$Description,$Name) Gets the Extended Network Error. GetError( $ErrorCode ) Gets the last Error for a Win32::NetResource call. GetUNCName( $UNCName, $LocalPath ); Returns the UNC name of the disk share connected to $Loc +alPath in $UNCName. NOTE $servername is optional for all the calls below. (if not + given the local machine is assumed.) NetShareAdd(\%SHARE,$parm_err,$servername = NULL ) Add a share for sharing. NetShareCheck($device,$type,$servername = NULL ) Check if a share is available for connection. NetShareDel( $netname, $servername = NULL ) Remove a share from a machines list of shares. NetShareGetInfo( $netname, \%SHARE,$servername=NULL ) Get the %SHARE_INFO information about the share $netname + on the server $servername. NetShareSetInfo( $netname,\%SHARE,$parm_err,$servername=NULL) Set the information for share $netname. EXAMPLE # # This example displays all the share points in the entire # visible part of the network. # use strict; use Win32::NetResource qw(:DEFAULT GetSharedResources GetError +); my $resources = []; unless(GetSharedResources($resources, RESOURCETYPE_ANY)) { my $err = undef; GetError($err); warn Win32::FormatMessage($err); } foreach my $href (@$resources) { next if ($$href{DisplayType} != RESOURCEDISPLAYTYPE_SHARE) +; print "-----\n"; foreach( keys %$href){ print "$_: $href->{$_}\n"; } }
        --
        Casey
        

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (8)
As of 2024-04-25 11:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found