[comp.unix.shell] Getting current shell to execute script

rhartman@thestepchild.sgi.com (Robert Hartman) (04/10/91)

In article <1991Apr9.164257.9128@agate.berkeley.edu> danabu@garnet.berkeley.edu (Daniel N. Abushanab) writes:
>
>Hi,
>I'm trying to write a script to ... find a directory that
>matches a pattern inputted by the user, then exit.  The following shell
>accomplishes that job.  Unfortunately, when the shell is exited it
>returns the user to the directory from which it was called.
> ...

Well, your problem is not in the script itself, but in the way it is
invoked.  Shell scripts run in a sub-shell; that is, another shell
process.  It isn't that the script "returns" the shell to the working
directory.  Your interactive shell never leaves the directory it's been
in all along.  It appears as though the script "returns" to the current
working directory because the interactive shell has been waiting for
it's child process (the one running the script) to exit before
prompting again.  If you ran your script in the background, the
interactive shell would prompt again immediately.

The cd command in your script tells that other shell to change
directory, not the interactive shell you've been typing in.

You have two options for getting the current shell to execute a
script.  The first involves converting your script into a shell
function.  Shouldn't be too hard to do that.  The syntax for an sh
function (which also works in ksh) is:

	function-name() {
	    list of commands
	}

You should be able to use your script as the list of commands with
little or no modification.

The other is to use the "." command.  This command tells the current
shell to take command input from a file.  Thus, if you said:

	$ . script

the current shell would execute commands from the file named "script."
But unfortunately, the "." command does not support passing arguments:

	$ cat > /tmp/foo
	echo $*
	^D
	$ . /tmp/foo bar

	$

However, you can use a function to get around this.  That is, the following
hack seems to work:

	$ foo() {
	    . /tmp/foo
	}
	$ foo bar
	bar
	$

The shell function passes arguments, which are expanded as the shell
interprets the script.  Thus, you can use the function to point your
current shell at a script maintained in a file.

So, the tidiest answer to your question would be to define a function in
your .profile that uses "." to source in your script:

	ncd() {
	    . $HOME/bin/ncd
	}

I can see a lot of .profiles getting a lot shorter real soon! ;^)
-r