Commit | Line | Data |
---|---|---|
2304df62 AD |
1 | Article 19995 of comp.lang.perl: |
2 | Newsgroups: comp.lang.perl | |
3 | Path: netlabs!news.cerf.net!mvb.saic.com!MathWorks.Com!europa.eng.gtefsd.com!howland.reston.ans.net!news.ans.net!malgudi.oar.net!chemabs!skf26 | |
4 | From: skf26@cas.org (Scott Frost) | |
5 | Subject: HOW TO source shell scripts into Perl | |
6 | Message-ID: <1994Mar21.191518.11636@chemabs.uucp> | |
7 | Followup-To: scott.frost@cas.org | |
8 | Keywords: Shell, Source, Dot | |
9 | Sender: usenet@chemabs.uucp | |
10 | Organization: Chemical Abstracts Service | |
11 | Date: Mon, 21 Mar 1994 19:15:18 GMT | |
12 | Lines: 139 | |
13 | ||
14 | A few days ago I posted a request for information on how to source | |
15 | a shell script into a perl script. In general, the responses indicated that | |
16 | it could not be done (although one came pretty close to the actual solution). | |
17 | ||
18 | A fellow staff member (who I was posting the request for) wasn't satisfied with | |
19 | the response and came up with a way. | |
20 | ||
21 | Before I indicate how he solved the problem, let me suggest some alternative | |
22 | methods of resolving this issue, | |
23 | ||
24 | 1. Hard code the environment variables directly in your PERL script. This | |
25 | is easy but unreliable. System administrators could change the | |
26 | production shell script environment variables and your PERL script would | |
27 | be hosed. | |
28 | ||
29 | 2. Create a shell wrapper that dots the shell script into your current | |
30 | environment and then invoke your perl script. This approach is easy | |
31 | to do, fairly full proof, but an affront to serious PERL programmers | |
32 | who believe PERL is God's gift to man (or at least Larry's :-) ). | |
33 | ||
34 | Chuck's solution involves running the script in the appropriate shell | |
35 | environment, dumping the shell's environment variables to a file, and then | |
36 | reading the environment variables into PERL's environment. | |
37 | ||
38 | It supports ksh, sh, csh, and zsh shells. It'll look at the first line of | |
39 | the file to be executed to determine the shell to run it under, if not found, | |
40 | it'll look at the SHELL environment variable. If the shell is not one of the | |
41 | four listed, it'll warn you and attempt to run the shell script under /bin/sh. | |
42 | ||
43 | A typical usage might look like this, | |
44 | #!/usr/bin/perl | |
45 | ||
46 | # Make sure dotsh.pl is placed in your /usr/perl/lib | |
47 | require "dotsh.pl"; | |
48 | ||
49 | print "SHELL_ENV_VAR = $SHELL_ENV_VAR\n" ; | |
50 | &dotsh('/tmp/foo') ; # script to run | |
51 | print "SHELL_ENV_VAR = $SHELL_ENV_VAR\n" ; | |
52 | ||
53 | /tmp/foo looks like this: | |
54 | #!/bin/ksh | |
55 | export SHELL_ENV_VAR="hi mom" | |
56 | ||
57 | The actual dotsh.pl script follows (BTW, this is now public domain): | |
58 | # | |
59 | # @(#)dotsh.pl 03/19/94 | |
60 | # | |
61 | # Author: Charles Collins | |
62 | # | |
63 | # Description: | |
64 | # This routine takes a shell script and 'dots' it into the current perl | |
65 | # environment. This makes it possible to use existing system scripts | |
66 | # to alter environment variables on the fly. | |
67 | # | |
68 | # Usage: | |
69 | # &dotsh ('ShellScript', 'DependentVariable(s)'); | |
70 | # | |
71 | # where | |
72 | # | |
73 | # 'ShellScript' is the full name of the shell script to be dotted | |
74 | # | |
75 | # 'DependentVariable(s)' is an optional list of shell variables in the | |
76 | # form VARIABLE=VALUE,VARIABLE=VALUE,... that 'ShellScript' is | |
77 | # dependent upon. These variables MUST be defined using shell syntax. | |
78 | # | |
79 | # Example: | |
80 | # &dotsh ('/tmp/foo', 'arg1'); | |
81 | # &dotsh ('/tmp/foo'); | |
82 | # &dotsh ('/tmp/foo arg1 ... argN'); | |
83 | # | |
84 | sub dotsh { | |
85 | local(@sh) = @_; | |
86 | local($tmp,$key,$shell,*dotsh,$command,$args,$vars) = ''; | |
87 | $dotsh = shift(@sh); | |
88 | @dotsh = split (/\s/, $dotsh); | |
89 | $command = shift (@dotsh); | |
90 | $args = join (" ", @dotsh); | |
91 | $vars = join ("\n", @sh); | |
92 | open (_SH_ENV, "$command") || die "Could not open $dotsh!\n"; | |
93 | chop($_ = <_SH_ENV>); | |
94 | $shell = "$1 -c" if ($_ =~ /^\#\!\s*(\S+(\/sh|\/ksh|\/zsh|\/csh))\s*$/); | |
95 | close (_SH_ENV); | |
96 | if (!$shell) { | |
97 | if ($ENV{'SHELL'} =~ /\/sh$|\/ksh$|\/zsh$|\/csh$/) { | |
98 | $shell = "$ENV{'SHELL'} -c"; | |
99 | } else { | |
100 | print "SHELL not recognized!\nUsing /bin/sh...\n"; | |
101 | $shell = "/bin/sh -c"; | |
102 | } | |
103 | } | |
104 | if (length($vars) > 0) { | |
105 | system "$shell \"$vars;. $command $args; set > /tmp/_sh_env$$\""; | |
106 | } else { | |
107 | system "$shell \". $command $args; set > /tmp/_sh_env$$\""; | |
108 | } | |
109 | ||
110 | open (_SH_ENV, "/tmp/_sh_env$$") || die "Could not open /tmp/_sh_env$$!\n"; | |
111 | while (<_SH_ENV>) { | |
112 | chop; | |
113 | /=/; | |
114 | $ENV{$`} = $'; | |
115 | } | |
116 | close (_SH_ENV); | |
117 | system "rm -f /tmp/_sh_env$$"; | |
118 | ||
119 | foreach $key (keys(ENV)) { | |
120 | $tmp .= "\$$key = \$ENV{'$key'};" if $key =~ /^[A-Za-z]\w*$/; | |
121 | } | |
122 | eval $tmp; | |
123 | } | |
124 | 1; | |
125 | ||
126 | ||
127 | ||
128 | ||
129 | ||
130 | ||
131 | ||
132 | ||
133 | ||
134 | ||
135 | ||
136 | ||
137 | ||
138 | ||
139 | ||
140 | ||
141 | ||
142 | ||
143 | ||
144 | ||
145 | ||
146 | ||
147 | ||
148 | ||
149 | ||
150 | ||
151 | -- | |
152 | Scott K. Frost INET: scott.frost@cas.org | |
153 | ||
154 |