http://qs321.pair.com?node_id=1196033

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

Hi guys, I need to execute 'tmboot -y' to startup application, and before that I need to run setenv.cmd to setup the environment. I have my code as below, but it was running with failure, stating 'tmboot' is not recognized as internal or external command. usually when I dont run setenv.cmd before 'tmboot -y', I got that error. but I already ran that in my script. I do not what is wrong with my script, thanks

use warnings; use strict; chdir "/server/setup"; my $env = system('setenv.cmd'); my $output = system('tmboot -y'); print $output;

Replies are listed 'Best First'.
Re: how to execute 'tmboot -y'
by hippo (Bishop) on Jul 25, 2017 at 18:31 UTC

    system spawns a child process and no child process can affect the environment of the parent. Therefore you should run both commands in a single system call if you want the environment to persist to the second command from the first.

Re: how to execute 'tmboot -y'
by haukex (Archbishop) on Jul 25, 2017 at 18:34 UTC

    Each call to system spawns a new subprocess, each with its own environment, changes made to one won't affect the other. Also, you seem to be expecting system to return the output of the command, which it does not, it returns its exit code. If and only if the external command you want to run is always a fixed string, then one way to do what you want would be:

    use IPC::System::Simple qw/capture/; my $output = capture('cd /server/setup && setenv.cmd && tmboot -y');

    However, as I said, this is only a good idea for fixed strings, because otherwise you may introduce security issues! I wrote about the topic of running external commands at length here.

    Update: Since I've added the cd to the command above, that change of working directory will not take effect for your script after the call returns. If you really want to change your working directory, then you should use Perl's chdir like you showed in your original code - perhaps just adding some error checking.

Re: how to execute 'tmboot -y'
by Mr. Muskrat (Canon) on Jul 25, 2017 at 18:31 UTC

    Perl is not the same as a shell script. Sure, you can do the same sort of tasks but you have to perform them slightly differently. A system call creates a sub-process that inherits its environment from its parent but it cannot affect its parent's environment. Try executing both 'setenv.cmd' and 'tmboot -y' within the same system call.

Re: how to execute 'tmboot -y'
by ytjPerl (Scribe) on Jul 25, 2017 at 19:42 UTC
    All of your answers are very useful. I have my code as below:
    chdir "/server/setup"; my $input = "daily.log"; print $file capture_merge {system('setenv.cmd&&tmboot -y')}; close($file);
    it is working. Thank you all again

      where is the open $file statement ?

      poj
Re: how to execute 'tmboot -y'
by ytjPerl (Scribe) on Jul 25, 2017 at 19:50 UTC
    I have another question about string match, when I get the output I have code as below to find a string, but the system just hauled, nothing comes back.
    open (FILE, "<<", $input;) while( <FILE>) { if (/"running"/s) {print "found";} }

      ytjPerl:

      Does your input actually contain the word running with quotes around it? If not, then remove the quotes from your regex.

      Also the input mode "<<" looks ... unusual. Are you sure you're doing it right? You might want to check for errors on your open.

      Your code is also syntactically goofy and has no chance of actually running. Next time, you might actually cut and paste the code in from your example, rather than rekeying it poorly.

      ...roboticus

      When your only tool is a hammer, all problems look like your thumb.