How to return programming to calling shell script?

Hi,
I need to edit a shell script which is calling another shell script. At the moment the program returns to the command prompt after executing each called script. I need to change it to make it return to the calling script so that the user is able to make another choice to execute the next option without coming out of the program and going back in each time.

For example the calling shell script LoadMarkID.sh is something like:

 
echo "Enter  L(Load id)   M(Mark id) :\c"
 read answer
 case $answer in
                       L) exec load_id.sh ;;
                       M) exec mark_id.sh ;;
                        *) invalid
esac
done

while called script load_id.sh is something like:

 
sqlplus -s userid/pswd  @load_id.sql
 
echo "Press Return to exit \c"
read answer
trap  1 2 3
exit 0

At this point, I would like the program to return to LoadMarkID.sh so that the user has a choice of selecting the next option without first exiting the program and then coming back in.

I would appreciate some help in achieving this please.

thank you.
PTL

remove the exit 0 line in the called script and wrap LoadMarkID.sh as follows

while 1 ; do
  clear
  echo "Enter  L(Load id)   M(Mark id) :\c"
   read answer
   case $answer in
                       L) exec load_id.sh ;;
                       M) exec mark_id.sh ;;
                        *) invalid
  esac
done
1 Like

Because you are using 'exec', your original program ceases to exist and is replaced by this new one whenever you do so. It cannot return because there's nothing to return to.

If you don't want it to do that, remove the 'exec' keyword and it will run it externally and wait for it to quit.

1 Like

wow!! You guys are great! thank you for both suggestions, I will try both and let you know how it goes.

thanks again.
PTL

hi,
Are there any more suggestions to the problem I logged please? I have tried both the suggestions above but neither was successful. The programming still does not return to the calling script.

thank you
PTL

Show your entire program, please, as well as the modifications you tried.

1 Like

Does your calling script do anything after the script call?

What happens (as far as we can tell) is:
Main script calls script 2
Script 2
preforms action
exit 0 (success)
Main script can get return status (exit 0) of the called script
Main script either performs other tasks below your task selection code (if there are any) or exits.

You can use the exit status of the called script to take additional actions in the calling script.

Shell scripting tends to be pretty linear in that when one command completes, the next will start. Running another script, from the perspective of your main script is just like any other command.
The task selection code you provided only allows for one task selection, then it is done.

If your intention is to remain in the main script's task selection code, then you need to write a loop around the task selection code and add an exit item to your task selection code.

As stated by Corona688, removing the exec leaves your main script running, and the command to run a second script returns as expected. What happens then is up to the code in the main script.

1 Like

PTL,
Skrynesaver and Corona688 both identified one third of your problems. (At least I assume that there is no command named invalid on your system.) You need to combine their suggestions to get rid of the problems they identified in your original script. Try:

while 1
do
        printf 'Enter  L(Load id), M(Mark id), or E(Exit): '
        read answer
        case "$answer" in
                (E) break;;
                (L) load_id.sh;;
                (M) mark_id.sh;;
                (*) echo 'Invalid choice, try again' >&2
        esac
done

And, I made a few other minor changes:

  1. I changed the first echo to a printf because it is more portable (since the behavior of echo "\c" varies from system to system).
  2. I removed Skrynesaver's clear command since I assume load_id.sh and mark_id.sh produce some output you want to see, and you need to at least be able to see the diagnostic if an invalid choice is entered.
  3. And, assuming that you didn't really want an infinite loop, I added a choice to let the user exit gracefully when they're ready to move on to another task.

I hope this helps.

1 Like

Wow!!! Thank you all again! I hadn't realised there were responses waiting for me, I was busy trying various other options.

You were all correct i.e. bits from each suggestion put together seem to have given me what I wanted. I used a while loop and I took out the 'exec' from the called script. The modification I had made before was to replace the exec with '.' which apparently was doing the same as 'exec' and hence no good. So what I have now done is to call the load_id.sh etc without 'exec' or '.'

thanks again. Hopefully that should be it.

PTL

It does something very different, actually.

With exec, the running program that calls the other script ceases to exist... There is nothing left to return to.

With ., your shell still exists, but a new one is not made... The new script is run literally inside the old as if the code had been typed right inside it. When it hits exit, it kills your shell.

When you run it without exec or . it creates a whole new shell to run it in, which dies without killing your original one.

Since you didn't post your code, I never guessed what you did. Please always post your code.

Hi Don,
The point you made about portability of "\c" is interesting. How do I get the cursor to go on to the next line i.e. what is the replacement for "\c" when I use printf?
I have indeed noticed that "\c" on our systeem, while it moves the cursor to the next line (which I want), displays itself as well which I don't really want.

thanks
PTL

By convention, when you print a prompt, you should leave the cursor at the end of the prompt and let the user's response provide the trailing newline character that will move the cursor to the next line.

On UNIX Systems, echo recognizes several backslash escapes including:
\a alert (screen flash or bell character or both)
\b backspace character
\f form feed character
\t tab character
\n newline character
\c stop looking for more text and skip trailing newline
and accepts no options. Any arguments starting with a - will be printed as is.

On BSD Systems, echo does not treat backslash as special, but has a -n option that will skip the trailing newline. Any other operands that look like options will be printed as is.

The standards allow either the BSD or the UNIX System behavior.

On Linux Systems, echo provides several options that are not allowed by the standards. Some of them recognize backslash escapes; some of them don't. Some of them skip the trailing newline; some don't.

Given the command:

echo -n -x -- "a\tb: \c"

A UNIX System (except OS X) will produce:

-n -x -- a	b: >>>Cursor here<<<

while a BSD System will produce:

-x -- a\tb: \c>>>Cursor here<<<

and a Linux System will do something different from either of the above.
A bug in OS X (which is supposed to be a UNIX System) prints the \t instead of replacing it with a tab.

As has been said many times in these forums before, if any of the operands to echo start with a minus sign or contain a backslash character, use printf instead of echo if you want to write a portable script.

PS The format operand to printf recognizes all of the normal C printf() backslash escapes. So, \n in the format string prints a newline.