Sourcing a Shell Script

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • rajataggarwal
    New Member
    • Mar 2007
    • 2

    Sourcing a Shell Script

    Hi,

    I am learning perl to do some test automation. In my perl scripts I need to source shell script. Can someone tell me whats wrong with the code below.

    Code:
    #!/usr/bin/perl
    
    system "source source.csh";
    
    $rajat = $ENV{'RAJAT'};
    
    if (defined ($rajat)){
    	print "RAJAT defined\n";
    }
    else{
    	print "RAJAT not defined\n";
    }
    *************** *************** ***********
    cat source.csh
    setenv RAJAT 1

    Is this the correct way to source a shell script from perl or is there any other way.
    Last edited by miller; Mar 22 '07, 01:29 AM. Reason: Code tag
  • docsnyder
    New Member
    • Dec 2006
    • 88

    #2
    @rajataggarwal

    Yes, in principle, shell scripts can be sourced with "source <script>" (you also could use the dot-form ". <script>").

    But, since system() starts a subshell, your environment variables do not get passed to the shell your perl script is running in. Even though your shell script exports variables, it will export them to the subshell, not to your actual shell.

    What exactly are you trying to do within the shell script? Maybe there is another way to solve it.

    Greetz, Doc

    Comment

    • miller
      Recognized Expert Top Contributor
      • Oct 2006
      • 1086

      #3
      Hello Rajat,

      Doc is 100 percent correct as for my knowledge covers what you're asking. This is specifically an issue with unix. You can read about it breifly from perldoc:

      perdoc perlfaq8 I {changed directory, modified my environment} in a perl script. How come the change disappeared when I exited the script? How do I get my changes to be visible?

      Another user also had a related issue a month ago:
      TSDN Perl Forum - Adding ENV variables in linux

      Anyway, as doc said, explain what you're ultimately trying to accomplish. It is likely there is a way around this specific requirement, but we won't be able to suggest anything unless you tell us more.

      - Miller

      Comment

      • rajataggarwal
        New Member
        • Mar 2007
        • 2

        #4
        Hi Doc, Miller,

        Thanks for the information. I am working on automating build, release, download and regressions for a product. Though its not compulsory for me to use Perl but I thought I will get to learn perl so started writing perl scripts.

        During the automation process, I need to sources lot of scripts from various vendors, These scripts are setting or appending lot of environment variables. So sourcing the script seemed the easiest way out to me. But if there is not way to source the csh script properly, then I might go back to either shell script or set the enviornment variables the csh script is setting in my perl script. Though I would not like to go for the later option. I get the scripts to be sourced from other vendors and if I set the environment variables, then everytime I get new scripts, I will have to go through them and correct my perl scripts.

        If you have any way around please let me know.

        Thanks,
        Rajat

        Comment

        • bidoun
          New Member
          • May 2007
          • 1

          #5
          I already had this issue with Perl three years ago. You can solve it by sourcing your script in a system command and then calling env to display environment variables you can then parse the output stream of the system command and extract the variable name and value with a regular expression then set inside the Perl code.

          It can seem quiet complicated but you can do it in a couple of hours.

          BR.

          Comment

          • prn
            Recognized Expert Contributor
            • Apr 2007
            • 254

            #6
            I thought I'd have a quick go at this just for laughs.

            I created a shell file called "setone":
            Code:
            #! /bin/bash
            export RAJAT="found"
            Then a quick perl file:
            Code:
            #! /usr/bin/perl
            use strict;
            
            my $rajat = $ENV{'RAJAT'};
            print "rajat = $rajat\n";
            
            my ($envar, $enval);
            open IN, ". ./setone; env |" 
              or die "Could not run shell: $!\n";
            while ( <IN> ) {
              chomp;
              ($envar,$enval) = split /=/,$_,2;
              $ENV{$envar} = $enval;
            }
            close IN;
            
            $rajat = $ENV{'RAJAT'};
            print "rajat = $rajat\n";
            
            print "bye\n";
            exit;
            The output of that is:
            Code:
            rajat =
            rajat = found
            bye
            That is, we started out without RAJAT as an environment variable, as we can see from the line "rajat = " used setone to set it within the perl script and then it was there. Pretty quick and painless. :)

            Enjoy,
            Paul

            Comment

            • gbowdridge
              New Member
              • Nov 2008
              • 1

              #7
              Two other methods would be to

              1) source the script prior to the execution of the perl script in a wrapper script

              OR:

              2) from the perl script, "exec" execute a list of commands that 1) sets a flag, 2) does the source 3) reinvokes the same perl script .

              when the perl script is called the second time, since it checks to see if the flag was set, it won't source the second time in and your file will be sourced in this environment.

              Code:
              #!/usr/bin/perl
              
              $script_to_source="/tmp/sourceme.sh";
              
              if($ENV{'SOURCED_IT'} != 1)
              {
                exec("SOURCED_IT=1;export SOURCED_IT;. $script_to_source ;$0 argument1 argument2 all arguments");
              }
              
              print "$script_to_source has been sourced\n";
              
              print "TESTVAR from source is set to $ENV{'TESTVAR'} \n";

              SHELL SCRIPT TO SOURCE:
              Code:
              TESTVAR="test value"
              export TESTVAR


              EXECUTION RESULT:
              Code:
              /tmp/sourceit.pl
              /tmp/sourceme.sh has been sourced
              TESTVAR from source is set to test value

              I wasn't able to figure out how to easily pass the same arguments that were passed into the script origionall into the second execution... I assume if i added that feature, then it would be as complicated as the previous examples, perhaps this is not the best method, but it is an interesting method.
              Last edited by eWish; Nov 20 '08, 01:52 AM. Reason: Added code tags

              Comment

              • KevinADC
                Recognized Expert Specialist
                • Jan 2007
                • 4092

                #8
                Welcome to bytes gbowdridge,

                just watch those thread dates, this one was about 18 months old. ;)

                Comment

                Working...