Curious bash source behaviour - comments?
I have just diagnosed a rather curious effect around my use of the bash
"source" statement.
It all started when I created a parameter driven version of a profile
script (in /etc/profile.d). This is because I wanted to reuse the same
script to setup the shell environment when I log on, and then later from
the command line to invoke the same script to switch the values of
certain variables based on the parameter. eg.
source /etc/profile ServerName
This is all very straight forward...or so it seemed, until I noted all
my cron jobs and init.d scripts were failing! WTF!
Well, after a hour pursuing the problem I discovered that the value of
$1 was being materialised as in scope within the script when called from
the init.d script. The profile script was seeing the parameter to the
init.d script (like "start" or "stop" etc) when invoked as ...
source /etc/profile
The fix was simple ... just invoke the "source" like this ...
source /etc/profile ""
and the $1 value is quenched for the called script allowing it to select
the correct default outcome.
I presume this is the expected behavior when source is used so that the
environment variables will be in scope for export commands etc buy
found it curious to say the least.
Anyway, its bit of a trap for new players, but I guess few ppl write
shell scripts these days ;-)
Cheers, Frank.
Re: Curious bash source behaviour - comments?
On 2005-11-10, Frank Hamersley wrote:[color=blue]
> I have just diagnosed a rather curious effect around my use of the bash
> "source" statement.
>
> It all started when I created a parameter driven version of a profile
> script (in /etc/profile.d). This is because I wanted to reuse the same
> script to setup the shell environment when I log on, and then later from
> the command line to invoke the same script to switch the values of
> certain variables based on the parameter. eg.
>
> source /etc/profile ServerName
>
> This is all very straight forward...or so it seemed, until I noted all
> my cron jobs and init.d scripts were failing! WTF!
>
> Well, after a hour pursuing the problem I discovered that the value of
> $1 was being materialised as in scope within the script when called from
> the init.d script. The profile script was seeing the parameter to the
> init.d script (like "start" or "stop" etc) when invoked as ...
>
> source /etc/profile
>
> The fix was simple ... just invoke the "source" like this ...
>
> source /etc/profile ""
>
> and the $1 value is quenched for the called script allowing it to select
> the correct default outcome.
>
> I presume this is the expected behavior when source is used so that the
> environment variables will be in scope for export commands etc buy
> found it curious to say the least.
>
> Anyway, its bit of a trap for new players, but I guess few ppl write
> shell scripts these days ;-)[/color]
The behaviour is as described in the bash man page:
source filename [arguments]
Read and execute commands from filename in the current
shell environment and return the exit status of the last
command executed from filename.
[....]
If any arguments are supplied, they become the
positional parameters when filename is executed.
Otherwise the positional parameters are unchanged.
--
Chris F.A. Johnson, author | <http://cfaj.freeshell.org>
Shell Scripting Recipes: | My code in this post, if any,
A Problem-Solution Approach | is released under the
2005, Apress | GNU General Public Licence
Re: Curious bash source behaviour - comments?
Chris F.A. Johnson wrote:[color=blue]
> On 2005-11-10, Frank Hamersley wrote:
>[color=green]
>>I have just diagnosed a rather curious effect around my use of the bash
>>"source" statement.
>>
>>It all started when I created a parameter driven version of a profile
>>script (in /etc/profile.d). This is because I wanted to reuse the same
>>script to setup the shell environment when I log on, and then later from
>>the command line to invoke the same script to switch the values of
>>certain variables based on the parameter. eg.
>>
>> source /etc/profile ServerName
>>
>>This is all very straight forward...or so it seemed, until I noted all
>>my cron jobs and init.d scripts were failing! WTF!
>>
>>Well, after a hour pursuing the problem I discovered that the value of
>>$1 was being materialised as in scope within the script when called from
>>the init.d script. The profile script was seeing the parameter to the
>>init.d script (like "start" or "stop" etc) when invoked as ...
>>
>> source /etc/profile
>>
>>The fix was simple ... just invoke the "source" like this ...
>>
>> source /etc/profile ""
>>
>>and the $1 value is quenched for the called script allowing it to select
>>the correct default outcome.
>>
>>I presume this is the expected behavior when source is used so that the
>> environment variables will be in scope for export commands etc buy
>>found it curious to say the least.
>>
>>Anyway, its bit of a trap for new players, but I guess few ppl write
>>shell scripts these days ;-)[/color]
>
> The behaviour is as described in the bash man page:
>
> source filename [arguments]
> Read and execute commands from filename in the current
> shell environment and return the exit status of the last
> command executed from filename.
> [....]
> If any arguments are supplied, they become the
> positional parameters when filename is executed.
> Otherwise the positional parameters are unchanged.[/color]
Tks - whilst I can happily live with this behaviour now that I know
about it I tend to prefer explicit forms as a rule. If I wanted the $1
value exposed to the called script I would happily code "source script $1".
But hey - I didn't write bash (or any of its predecessors) so "c'est la
vie".
Cheers, Frank.