[net.unix] arguments for a command file

kapil@dartvax.UUCP (12/19/84)

*** REPLACE THIS LINE WITH YOUR MESSAGE ***
 
I am facing a problem writing a command file. I would like this file
to be run with an argument supplied. The command it executes is cd.
the argument is the pathname it should default to. the command file
enables the 25th line prints the new directory in reverse video,
clears the screen and repositions the cursor at the top of the screen.

I am attempting to pass the argument by --
cd $1
Is this the right way of doing it?
I print the pwd in the command file and it prints the expected one.
On using the command pwd outside the command file I find that the
change in the directory has not been made.
Why does it do this?

seifert@mako.UUCP (Snoopy) (12/21/84)

> I print the pwd in the command file and it prints the expected one.
> On using the command pwd outside the command file I find that the
> change in the directory has not been made.
> Why does it do this?

When you execute the command file, a child process is set up.
The current directory *in the child process* is in fact
getting changed, but this does not effect the current directory
in the parent process.

If you in fact want the command file to change the current directory
in the parent process (normally your login shell), you have to
get the shell to *not* set up a child process to execute the
command file. This is done with the dot command.

e.g.:

$ pwd
/usr
$ . command_file include
$ pwd
/usr/include
$

This also applies if you want to set shell variables from
a command file.

Just tried this, and $1 will get the argument if you don't use
the dot command, but doesn't when you do.  Very strange. Might be
a Berkelyism, but I no longer have access to sys V to compare with.

        _____
	|___|		the Bavarian Beagle
       _|___|_			Snoopy
       \_____/		tektronix!tekecs!seifert <- NEW ADDRESS !!!
        \___/

alb@Mitre-Bedford (12/22/84)

The catch is that when you run the program as a command, it runs as
a child of the present shell. That is why the cd in the file doesn't
effect the parent shell.

A way to have the shell file make changes in the present shell is to
use the source command, which interprets the commands with the present
shell. Unfortunately this complicates the argument passing.  You could
read the argument from stdin once the the file is running.

len

rpw3@redwood.UUCP (Rob Warnock) (12/22/84)

[ Wizards, no flames please... net.unix IS for novice questions, occasionally.]
[[ ...besides, we can't put EVERYTHING in net.announce.newusers ;-} ]]

+---------------
| I am facing a problem writing a command file. I would like this file
| to be run with an argument supplied. The command it executes is cd.
| the argument is the pathname it should default to...
| I am attempting to pass the argument by -- cd $1
| Is this the right way of doing it?
+---------------

Yes, this is the right way, generally speaking, to pass an argument to
a shell script. If you want it to default to some value, you can do use
the "${1-foobar}" construct, which will cause the argument to default
to "foobar" if you don't give it one.

+---------------
| I print the pwd in the command file and it prints the expected one.
| On using the command pwd outside the command file I find that the
| change in the directory has not been made.
| Why does it do this?
+---------------

The "current directory" is a property of each process, not of your
interaction with the terminal (sometimes called your "job"), although
new processes inherit a "current directory" from their parent process
when created ("forked").

When you execute a command file (or script), your current shell creates
a new process for the copy of the shell which is interpreting the command
file. When you change the "current directory" in your script, it ONLY
affects commands executed INSIDE the script from that point on. Your
login shell was never affected, since it never saw the "cd" command.

In fact, for this reason, the shell must execute the "cd" command
itself, without running a program. For if "cd" were a program, a
new process would be created for it to run in (as is done for ANY
program), the "current directory" would be changed FOR THAT NEW PROCESS
ONLY (i.e., the "cd" program), and your login shell would never see it.

There ARE ways to use scripts to help move your current directory around,
but it gets a little messy. You must cause your current shell to actually
read the script itself, and NOT invoke a sub-shell to read it. This can be
done if you are using the Bourne Shell (a "$" prompt) with the "." command
(yep, just a dot!). If you put the following in a file named (say) "cdnews":

	olddir=`pwd`
	cd $HOME/news
	echo 'Now in your "news" directory from' $olddir

you can type ". cdnews" (don't forget the space after the dot), and this
will do the sort of thing you wanted. (Depending on your shell, you may have
to type ". $HOME/cdnews" if "cdnews" is in your home area and you aren't.)
(Notice that you can "cd $olddir" to get back.)

If you are using the Berkeley C-shell "csh" (usually a "%" prompt), you
can use the "source cdnews" command, instead of the dot (it does the same
thing), but it's a lot easier to define some aliases to help you. Type
the command

	alias cdnews 'source $HOME/cdnews'

and from then on you can just say "cdnews", which is what you were trying
to do originally. If you do this a lot, it is good to put such aliases in
your ".cshrc" or ".login" files. Find a local friend or wizard to help.


Rob Warnock
Systems Architecture Consultant

UUCP:	{ihnp4,ucbvax!dual}!fortune!redwood!rpw3
DDD:	(415)572-2607
USPS:	510 Trinidad Ln, Foster City, CA  94404

ian@utcs.UUCP (Ian F. Darwin) (12/23/84)

	[The original posting describes using `cd' inside a shell file]
	I am attempting to pass the argument by --
	cd $1
	Is this the right way of doing it?
	I print the pwd in the command file and it prints the expected one.
	On using the command pwd outside the command file I find that the
	change in the directory has not been made. Why does it do this?

This is a well-known feature of UNIX. You can cd in a shell file
and it won't hurt your main shell. Thus people writing command
files can cd all they want. But it wasn't intentional, it just
worked that way. In fact, the first people to make the same mistake
you made were Thompson and Ritchie, when they were writing the
current version of UNIX process creation(note 1)! This happens
because the shell is a child process of your interactive shell;
in general a child process cannot change the parent process' environment, 
current directory, etc, etc. And it must be so, otherwise you could change
system processes!

If you do want to change your current directory from within a shell file,
try invoking the shell file as
	. shellfilename newdirectory
if using the real (Bourne) shell, or
	source shellfilename newdirectory
in the C shell. But if all you want is to change directory, use the
cd command. As you can see from the description,
the cd command must be built into the shell.

----------------
Note 1 - See the paper "The Evolution of the UNIX Time-Sharing System"
by Dennis Ritchie. This paper has been reprinted in several places
in 1984, including the October 1984 (AT&T)Bell Labs Technical Journal
and the October 1984 Microsystems (the final issue of Microsystems,
November 1984, has a follow-on paper by myself and Geoff Collyer
with further information on the history of UNIX at Bell Labs).
The discussion of chdir is on page 1585 of the reprint in the BLTJ issue.
-- 
Ian Darwin, Toronto
{ihnp4|decvax}!utcs!ian

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (12/26/84)

The effect of "cd" cannot be exported outside the shell script
to the invoker of the script.  That is why "cd" is a shell
built-in instead of an executable command in /bin.

colonel@gloria.UUCP (George Sicherman) (12/28/84)

[If it moves, eat it.  --Vogon proverb]

> I am attempting to pass the argument by --
> cd $1
> Is this the right way of doing it?
> I print the pwd in the command file and it prints the expected one.
> On using the command pwd outside the command file I find that the
> change in the directory has not been made.
> Why does it do this?

Because a child cannot change its parent's environment.  Maybe
you should consider aliasing.
-- 
Col. G. L. Sicherman
...seismo!rochester!rocksanne!rocksvax!sunybcs!gloria!colonel