CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script

 



alex5161
Novice

Feb 28, 2018, 11:06 AM

Post #1 of 13 (10440 views)
In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script Can't Post

I have reviewed many examples on-line about running another process (either PERL or shell command or a program), but do not find any useful for my needs way.
(Reviewed and not useful the system(), 'back ticks', exec() and open())
I would like to run another PERL-script from a first one, not exiting from the first one (as by exec()), not catching the STDOUT of the called script (as in the back tick processing,) but having it printed out, as in initial script (as it is by system()) while I do not need the return status (as by system()); but,
- I would like to have the called script to set some variables
, that will be accessible in the calling script (sure, set by the our @set_var;)

My attempt (that I am not able to make do what I need) is:

Script1 is something, like:

Code
... 
if($condition)
{ local $0 = 'script2.pl';
local @ARGV = ('first-arg', 'second_arg');
do script2.pl;
}
print "set array is: '@set_var'\n";
...

The 'script2' would have something like:

Code
#!/usr/bin/perl 
...
print "having input parameters: '@ARGV'\n";
... # all script activities
our @set_var = ($val1, $val2, $val3);
exit 0;

The problem in my code is that the do ... command is executed on beginning of the first script run and is not in the place, where it is prepared for it (by setting some local .. vars!)

I did try to use the eval "do script2.pl" : - now it is executed in the proper place, but it is not setting the @set_var into the first script process!

Is there any idea to do it as I would like to have it?
(I understand, that I can rewrite the script2.pl, including whole processing in some function (say, main()) and load it by require() and execute the function main(): that will do everything as I prefer it; but I would like to leave the second script as-is to be executable from shell by itself, as it is now.
... and I do not like the way to pass values by a flat file...)

Does anybody have an idea how to do my whim?


BillKSmith
Veteran

Feb 28, 2018, 8:43 PM

Post #2 of 13 (10433 views)
Re: [alex5161] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post

Sorry, this is not possible. The reason has nothing to do with perl. This is a constraint of all operating systems that I know of. A child process can access the values set by the parent, but the parent cannot access values set by the child.

There are other ways you can return information. You have already mentioned the returns from back-tics and system. You could use a socket to access the stdout of the child as if it were a file. The easiest way is to use a real file. You can use it to return perl variables with the help of the CPAN module Storable.
Good Luck,
Bill


FishMonger
Veteran / Moderator

Mar 1, 2018, 7:39 AM

Post #3 of 13 (10430 views)
Re: [alex5161] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post

Sounds like you have an XY problem.

What is the real problem that you need to solve which lead you to wanting to try to solve it in this way?

Maybe a simple config file will meet your needs? Or use the Storable module as suggested by Bill. Or use a database.


alex5161
Novice

Mar 1, 2018, 12:49 PM

Post #4 of 13 (10421 views)
Re: [FishMonger] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post

 Thank, BillKSmith and FishMonger for the pretty the same answer with advise to use a file to communicate processes.
My point is in position: if a script is in Perl, it is sounds foolishly to have another 'piece of the Perl-code' be a separate process, unless it is decided!
After all, the second script could be just copied into the first one.
That is another 'bad way' to resolve it, besides a file.
Up to now I have covered all functionality of the second script in the function 'main_scr2()' and used 'requre()' in first fcript to load it to first-script area and run the 'main_scr2()' with needed parameters, having that function setting needed variables.
So, like that:
- In script 1:

Code
....  
require 'script2.pl';
eval "main_scr2 ('parm-1', 'parm-2')";
print @set_var;
....

- In script 2:

Code
my $itself = ($0 =~ __FILE__);  # set indication of current use 
if ($itself) {
... # all the process initialization steps
main_scr2();
}
else { 1; } # for calling from a script by 'require(): need TRUE returned

sub main_scr2
{
@input = @_ ? @_ : @ARGV;
.... # all script functionality
our @set_var = ($val, $val1,...);
exit 0 if $itself;
}

Not elegant, but better than a file in any way (including the 'Storable')

Anyway, thanks for participation!

FishMonger
BTW, I am not guessing what the 'an XY problem' is. Not familliar with such idiom, if it is...


(This post was edited by alex5161 on Mar 1, 2018, 12:55 PM)


FishMonger
Veteran / Moderator

Mar 1, 2018, 1:41 PM

Post #5 of 13 (10413 views)
Re: [alex5161] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post

Definition of XY problem - https://en.wikipedia.org/wiki/XY_problem


Quote
[ incomplete code snippets left out ]
Not elegant


You are right about that; it couldn't get much farther away from being elegant.

Using a proper module inplace of 'script2.pl' would be much cleaner/elegant and easier to maintain.


(This post was edited by FishMonger on Mar 1, 2018, 1:42 PM)


FishMonger
Veteran / Moderator

Mar 1, 2018, 4:52 PM

Post #6 of 13 (10408 views)
Re: [alex5161] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post

Here's a module example based on your code snippets.

script1.pl

Code
#!/usr/bin/perl 

use warnings;
use strict;
use MyModule qw( main_scr2 );
use Data::Dumper;

my @set_var = main_scr2('parm-1', 'parm-2');

print Dumper \@set_var;


MyModule.pm

Code
package MyModule; 

use strict;
use warnings;
use Exporter;

our @ISA = qw(Exporter);
our @EXPORT_OK = qw( main_scr2 );


sub main_scr2 {

my @input = @_;

# do something with @input

# return processed results
return ('val-1', 'val-2', 'val-3');
}

1;


Output

Code
c:\test>script1.pl 
$VAR1 = [
'val-1',
'val-2',
'val-3'
];



(This post was edited by FishMonger on Mar 1, 2018, 5:12 PM)


Laurent_R
Veteran / Moderator

Mar 1, 2018, 11:23 PM

Post #7 of 13 (10403 views)
Re: [alex5161] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post


Quote
My point is in position: if a script is in Perl, it is sounds foolishly to have another 'piece of the Perl-code' be a separate process, unless it is decided!


That's the way all operating systems in common use nowadays work. And this is not weird: if you want to run another program while your program is waiting, starting another process is a quite legitimate way to do it


Quote
After all, the second script could be just copied into the first one.

Yes, if you're not happy with returning a value to the main program, that's exactly what you need to do, one way or another. There are at least half a dozen ways to do that (copy and paste the code, eval, require, use, etc.), but using a module is probably the cleanest and also the easiest.


(This post was edited by Laurent_R on Mar 3, 2018, 2:06 AM)


BillKSmith
Veteran

Mar 2, 2018, 7:27 AM

Post #8 of 13 (10398 views)
Re: [alex5161] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post

The module approach suggested by both FishMonger and Laurent is probably the best solution. It is an example of a trade-off we often have to make. A little extra work in the beginning saves us time in the long run.

If, despite this, you are still tempted to use cut/paste, there is a third option. do EXPR effectively pastes the contents of a file into your code.
Good Luck,
Bill


FishMonger
Veteran / Moderator

Mar 2, 2018, 8:31 AM

Post #9 of 13 (10396 views)
Re: [alex5161] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post


Quote
My point is in position: if a script is in Perl, it is sounds foolishly to have another 'piece of the Perl-code' be a separate process, unless it is decided!

Your solution creates a separate process, which you seem to dislike but also think it's the best solution, whereas my suggested module solution doesn't create a separate process and is cleaner and easier to understand and maintain.


Quote
After all, the second script could be just copied into the first one.
That is another 'bad way' to resolve it, besides a file.

Why would that be a "bad way" to resolve it? If written properly i.e., using various subs and/or an embedded module, having everything in a single script/file could be a good choice and it's not uncommon. It really depends on the size and complexity of the code.


(This post was edited by FishMonger on Mar 2, 2018, 8:36 AM)


alex5161
Novice

Mar 2, 2018, 3:24 PM

Post #10 of 13 (10391 views)
Re: In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post

[FishMonger],[BillKSmith],[Laurent_R]:
I am agree that 'module' way slightly cleaner.
Yes, after forming the second-script functionality into a function, it is easy to 'use ...' it and avoid the 'eval ...', having the function already known to first script.
But, that is it. There is no really any difference between my final and advised as a 'modular' solution!
And it works the same way!
Yes, the 'use ..' could be moved on beginning, but it does not a matter: still loaded in same processing time: before starting the 'script-1'
To leave (as it is stated from beginning) ability to use the second script by itself, still some overhead coding should be done in the second script and that is not changed at all by 'modular' solution.

So, after that, [FishMonger], I do not see where is your modular suggestion any how more 'elegant' than my?!
Well, little difference in code readability is exist by returning the array of values, instead of setting it in 'our ..' scope in second one.
But that correction could be done in my solution and not really changing the approach (which is not nice in general.)
And, [FishMonger], you are not right that my way to resolve it starting another process: it execute the function from loaded already second script in current process!! ... unless you mean, the eval() is done in the separate process... I would doubt on it; seems to me, the eval() is processed in the same... While, anyway, I have already accept that suggestion to replace the 'require' by 'use' and have removed the 'eval'!

Also, I do not see a real need in making the second one a 'package', use 'exported' and (well, it is habitual, understanding, but) the 'strict' and 'warnings'. (I perfectly coding in Perl for 4 years by now and newer used those both. ... I understanding all benefits of it,but leave perfectly...!)

!!!!!!!!!!!!!!!!!!!!!
After all !!
[BillKSmith] -- IT IS COMPLETELY WHAT I WAS LOOKING FOR!!!
- the 'do EXPR'!
(I fill like I do remember it was something, works exactly as I planed, but was not able to recall and have had doubts if I am mistaking... So, came to ask people on-line...)
Sure, it is what I need:
- it is executing in place where it written;
- it uses and creates variables in the same process space;
- it is not needed to be copy-and-past
- and (whith minimum addition on exit way) it stay executable by itself while could be ran in script-1 !

(So, how it is on 3 forums people couldn't guess that way, besides what the blindness happening with me, I am not understanding...)

Any way, big thanks to all and, especially, to [BillKSmith]!!!


BillKSmith
Veteran

Mar 3, 2018, 7:37 AM

Post #11 of 13 (10374 views)
Re: [alex5161] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post

There is a reason it was hard to find a solution that you liked. You asked the wrong question. In your original post, you asked about running another process. When you asked about 'variables', I assumed that you mean 'environmental variables'. FishMonger recognized this post as an XY problem, guessed at the underlying problem and proposed a solution. You still have not described the underlying problem, but continue to ask for help with your 'solution'. I seem to have stumbled on an answer to that question. This is seldom a good solution to any problem. Of course, this may be the exception. We really cannot help you decide because we still do not know enough about the real problem.
Good Luck,
Bill


FishMonger
Veteran / Moderator

Mar 3, 2018, 8:29 AM

Post #12 of 13 (10371 views)
Re: [alex5161] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post


Quote
To leave (as it is stated from beginning) ability to use the second script by itself,


A module can be executed as a standalone script (if you want to code it that way) in addition to using it in the normal manner by loading it via a use or require statement. Using it as a standalone script is very unusual and usually signifies a poor design choice.

As Bill already pointed out, we can't really provide you with the best answer because you haven't provided the proper info about what you're doing/needing. Bill's solution guess which appears to be what you wanted, but is not necessarily the best solution, was just that; a guess. It was not based on a clear understanding of what you needed.

The fact that you posed your question on 3 different forums and expected everyone to guess like Bill did is clear evidence that you posed an XY problem/question.


(This post was edited by FishMonger on Mar 3, 2018, 8:34 AM)


alex5161
Novice

Mar 3, 2018, 2:23 PM

Post #13 of 13 (10360 views)
Re: [FishMonger] In a perl-script trying to execute another perl-script that SETS SOME VARIABLES for caller script [In reply to] Can't Post

 Honestly, I do not understand why you both complaining that my question is not clear?!
(Nothing negative, but i would like to get it.. I've already mentioned about my appreciation of your communication to me and it will not be changed! I am continue not with irritated arguing, but to get some reasonable points to myself...)

[BillKSmith] Blames me to asking for a process: '..you asked about running another process.'
No, I did not, while did not excluded it.
I mentioned that I checked running another process, but did not said I need exactly that.
Even in title it exactly said what I am looking for. Just did not mentioned in the title that the called script should received decided by first script parameters.
In the third sentence I repeat the title question with more explanation and with negative point of using any possible solutions for running piece of external code!
I could accept blame that I did not enough mentioned that the second script has to have some input from first, thinking that is visible by example...
But the request to have some return from the second one is clear and repeatedly mentioned.
And only 'do ...' is suitable for that, having not using a flat file to communicate scripts...

About [FishMonger] announce of the '.. a poor design choice.. )
it is hasty conclusion!
Both scripts are part of the whole process that has couple significant steps that frequently required results review, but, still assumed to have a chance to be executen by one command.
Actually, that is what I am providing by combining multiple modules into one process (the script 1 in my example.)
And, again, the second script should still be useful to process that step separately.
Anyway, whole process is the existing one, that always processed by set of steps and it is not possible (by time and complicity) redesign it completely, while I would, definitely, do that, if my opinion would be final!
(Speaking about the 'poor design', I could only envy to [FishMonger] if you are working in the system with all smart design everywhere! For my more than 25 year of developing experience I have never meat even 'not bad' designed system! (and that is Medicate/medicare; systems on Chrysler, on Ford, and now on GM!) I would say: than bigger and complicated a system, than poorly it designed!)

'the XY problem': again disagree!
I did not presented a solution Y, asking to fix it (as it explained in Wikipedia.)
Instead, I've presented my try and mentioned what is wrong on it! I assumed to eliminate such suggestion on responses, presenting why it is not suitable for me! I am not sure how any presented bad solution could be assumed as an ask to fix it!
And, on my filling, the problem X, I have asked, is enough obvious: need to run a script in middle of first one, having second one setting some vars (I am lost how else I could name variables to do not apply to term 'environment variables' .. And why in a question about the Perl script it should be referred to a shell variables, I am not guessing. There is nothing about shell in all messages, besides the word 'process', that comes from the Perl-commands, like 'system()' 'back-tick', 'exec()')
I intend to think, that the XY problem is built in reader's minds by intention to guess something that is not obviously asked, in assumption, that the requester has no ability to see a real problem and the reader will better understand what the requester need, instead of what he is asking!

So, once again, I am appreciate your support in my search and your help, but disagree in blames.
And it is not to say: 'that is it; do not want to hear anything more', but, instead, reflection that I am not convinced in presented blames on my bad asking.

I agree, something is not good in my way to present the problem if on 3 forums there is no understanding; but, mentioned points does not sound as a real reason.
Maybe it is not organized as expected, maybe it has extra points that are misleading, maybe used terminology is not standard and assumed, ... but, all that just my guesses that are not meaningful until I would hear confirmation from outside...
One point I accepting clearly: I did not obviously mentioned about the need to have the script-2 parameters be prepared in the script-1.
Yes, that point some how been in my mind as clearly obvious.
But, it is not enough to be not understood...


(This post was edited by alex5161 on Mar 3, 2018, 2:50 PM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives