LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   shell related query !!!!!!!!!!! (https://www.linuxquestions.org/questions/linux-general-1/shell-related-query-648047/)

iacharyya 06-09-2008 10:35 AM

shell related query !!!!!!!!!!!
 
hi ,

my question is below:

i have a main shell script, say, main.sh, within main.sh i have invoked / called two more shell script, say, A.sh & B.sh.

now A.sh changes major in the system, say, changes the lib path,

at this point (1) will main.sh will be able to know the changes that made by A.sh, if not then (2) how to inform main.sh about this change.

Regards,
Indranil

GrapefruiTgirl 06-09-2008 12:06 PM

If A.sh EXPORTS the changes as necessary to the appropriate environment variables, and/or updates the linkers' search locations by means of `ldconfig` then the changes would be effected from that point onward.

Perhaps providing specifics about what you are trying to accomplish would get you a more concise answer.

SVA

forrestt 06-09-2008 02:12 PM

The script main.sh won't know about the changes.

If an environment variable is changed inside a script (which in effect starts a new shell) the parent shell doesn't know about the change.
Likewise, a script that calls another shell wont know about the environment variables of that shell. If an environment variable is set (and exported) the only things that know about the value are the current shell itself and processes that shell forks, not the parent shell.

The LD_LIBRARY_PATH variable is set when the shell is started, it doesn't constantly get reset. If in your example, a.sh resets the library path with ldconfig, then I don't even think that it (a.sh) will know about the change (although next time the script is run, it will know about any prior changes). In that example, however, b.sh SHOULD know about the change as it is being started AFTER the library path is modified.

You may be able to reload things with "exec bash" after a script changes the global systems settings, I'm not sure (and I don't have a system I can test it with).

HTH

Forrest

GrapefruiTgirl 06-09-2008 02:39 PM

This is interesting; I may stand corrected by Forrestt, though I too am inclined to test this out.

I thought environment variables were global variables, taking effect globally and universally under normal circumstances?

If not, then it would be safe to assume (until learned otherwise) that if a shell environment variable is set and exported from within a shell/script, that very shell/script does not know about it? Doesn't really make sense, but again, I will test this out.

EDIT: The Test for exporting variables:

File main.sh:
Code:

#!/bin/bash

export VARIABLE="Hello-one"
echo $VARIABLE
./a.sh
echo $VARIABLE
exit 0

File a.sh:
Code:

#!/bin/bash

export VARIABLE="Hello-two"
echo $VARIABLE
exit 0

results:
Code:

bash-3.1$ ./main.sh
Hello-one
Hello-two
Hello-one
bash-3.1$

So shell # 1 did not pick up the change to the variable made in a.sh (shell # 2).
I stand corrected, and wiser :)
I did not go to the extent of changing around my library paths to test ldconfig. Perhaps the OP can tell us what happens?

Perhaps also a workaround for the OP would be to have main.sh in two or more parts:
main.sh does its thing, then calls a.sh which changes some variables. a.sh THEN does not return to the original main.sh, but instead executes for example main2.sh, which will be aware of the variables and work accordingly? And so on...

Thanks for enlightening us Forrestt!

Sasha

forrestt 06-09-2008 03:44 PM

Quote:

Originally Posted by GrapefruiTgirl (Post 3179608)
Thanks for enlightening us Forrestt!

Sasha

You're Welcome.

I did find the solution though:

Instead of running the scripts like, "./a.sh" run it like, ". ./a.sh". You also can't have the exit 0 in the sub-scripts.

So, your scripts would look like:

File main.sh:
Code:

#!/bin/bash

export VARIABLE="Hello-one"
echo $VARIABLE
. ./a.sh
echo $VARIABLE
exit 0

File a.sh:
Code:

#!/bin/bash

export VARIABLE="Hello-two"
echo $VARIABLE

Results:
Code:

% ./main.sh
Hello-one
Hello-two
Hello-two

HTH

Forrest

GrapefruiTgirl 06-09-2008 04:33 PM

To exit 0 or not to exit 0.
 
Quote:

Originally Posted by forrestt (Post 3179671)
...You also can't have the exit 0 in the sub-scripts...

Please expand upon that-- why not? Though my method did seem to work (except the EXPORT bit) what did/does the 'exit 0' make different?

Thanks!

forrestt 06-09-2008 04:47 PM

If you have the exit 0 in the sub scripts it kills the main script as well and you don't return back to continue it. Instead, you end up with:

Results:
Code:

% ./main.sh
Hello-one
Hello-two

Forrest

GrapefruiTgirl 06-09-2008 04:54 PM

That is when using YOUR solution of adding the '.' when calling the subscript, correct?

I ask because in the way I tried first, the subscript did have the exit 0, but execution did in fact return to the initial script.

Sasha

forrestt 06-09-2008 05:19 PM

Yes, but the variable didn't get updated. This is because the exit 0 was exiting from the new shell that was executed at the top of a.sh, not the shell that was calling it in main.sh, and like we said before, changes to an environment variable can only be seen by the current shell or child processes.

The "." is basically saying, "don't start a new shell, just run the commands found in this file from this shell". It's sort of like an include in other languages. Without the "." you are starting a new shell (as noted by the first line of the script).

Code:

#!/bin/bash  <-- This says start a new bash shell, but is a comment if called with the "."

export VARIABLE="Hello-two"
echo $VARIABLE
exit 0

When it gets to the "exit 0" it is running that command as if it were part of the main.sh script and dutifully exits.

I didn't mean to imply that you couldn't have an "exit 0" inside a sub-script, only that you couldn't have an "exit 0" inside a sub-script if you want to use the "." shell call.

HTH

Forrest

GrapefruiTgirl 06-09-2008 05:44 PM

Perfect! Thank you, Forrestt, for that excellent clarification :)

Sasha

GazL 06-09-2008 06:39 PM

If you really want to pass variables back then this is one trick, though its a bit of a hack and it uses a temporary file.

a.sh
Code:

#!/bin/bash

# run secondary shellscipt

./b.sh

# use source to get the variables back
. /tmp/variables.$$

echo A is $A
echo B is $B

exit 0

b.sh
Code:

#!/bin/bash

# create a temp file containing variable assignments
echo A=2000 >/tmp/variables.$PPID
echo B=3000 >>/tmp/variables.$PPID

exit 0

The other option is to pass them back on stdout and capture them with a read but that can get messy as you need to ensure that stdout doesn't get filled with any other output from the sub shell.

If you have to resort to this sort of stuff though, its usually better to just rework your scripts so the main one sets everything it can.

Anyway, this might give you some ideas. Hope it helps.


All times are GMT -5. The time now is 03:22 AM.