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