johnhi@tekig5.UUCP (John Higley) (01/25/86)
Where are you after a batch file completes? Wherever it chooses to leave you. Where do you want to be? Back where you started. How can you get there automatically? I have just written a c program that reads the current working directory and outputs it. This output is just right for a batch file to return you to where you want to be. If any one is interested, send me e-mail. John Higley ...tektronix!tekig5!johnhi
keifer@uiucdcs.CS.UIUC.EDU (01/28/86)
You can get the current directory by using the CD (CHDIR) command without any arguments. You get something like C:\TEMP or whatever.
hes@ecsvax.UUCP (01/28/86)
> Where are you after a batch file completes? Wherever it chooses to leave > you. Where do you want to be? Back where you started. How can you get > there automatically? > ... In pc-dos 2.1 - if you do a cd in the .bat file you are left in that directory, otherwise you stay in the same directory. (Am I missing something?) > John Higley > ...tektronix!tekig5!johnhi --henry schaffer
connery@bnrmtv.UUCP (Glenn Connery) (01/28/86)
> Where are you after a batch file completes? Wherever it chooses to leave > you. Where do you want to be? Back where you started. How can you get > there automatically? > > I have just written a c program that reads the current working directory and > outputs it. This output is just right for a batch file to return you to > where you want to be. If any one is interested, send me e-mail. > > John Higley > ...tektronix!tekig5!johnhi But just doing "CD >somefile" gets you that. What you really want is programs that PUSH and POP the current directory, so that they can handle nested calls (I use them both in CED synonyms and in batch files). Glenn
ray@othervax.UUCP (Raymond D. Dunn) (01/30/86)
For those people who made trite comments about the batch file directory posting, please think a little before hitting 'f'. If you have to say "am I missing something", then yes, you probably are. The problem being solved by the referenced program is how to return to the directory current at the start of a batch file which does directory changes, i.e some sort of pushd and popd. If anyone thinks this can be done with normal commands without it taking forever, I for one would be very interested in the solution! This is a common problem in Dos, particularly when calling (sick)programs in a batch file which do not understand paths, you have to cd to the directory of the required file, call the program which uses that file, and then ... what? The batch file does not know what its initial current directory was. The only solution I know using Dos commands and which I regard as an unacceptable cludge, is to have a file say xx in a known place which contains only the characters c, d, and space (no terminating return). The batch file should now look like: copy \dd\xx \pp\popd.bat [ copy the "cd " into file popd.bat, where pp is a directory in your PATH (2.1), or use \pp\popd in the call below (3.1). echo cd > popd.bat can not be used because echo always outputs a terminating return ] cd >> \pp\popd.bat [ append the current directory path to the "cd " ] . . [ the required batch file commands which . include one or more cd's ] . popd [ which executes the cd to the initial directory. note that if commands are require to follow this in the batch file, it should be: command /c popd ] As an aside, this is another example of the stupid non-consistency of Dos. The PATH command with no arguments displays(writes) the line PATH=....., however cd with no arguments just displays the directory path with no initial "cd ". Ray Dunn ..philabs!micomvax!othervax!ray
glen@intelca.UUCP (Glen Shires) (01/30/86)
> > Where are you after a batch file completes? Wherever it chooses to leave > > you. Where do you want to be? Back where you started. How can you get > > there automatically? > > ... > In pc-dos 2.1 - if you do a cd in the .bat file you are left in that > directory, otherwise you stay in the same directory. (Am I missing something?) > > > John Higley > > ...tektronix!tekig5!johnhi > > --henry schaffer Often you can get around this by specifying a programs full path name like: c:\yourdir\yourfile Also, you can use the DOS "PATH=c:\;c:\yourdir" command But not always... For those programs that must run with the current directory elsewhere here's a hack around your problem: create a dummy skeleton file in root CDMSG.BAT containing only "CD " (CD<space>) NO CARRIAGE RETURN then put in your batch file: copy c:\cdmsg.bat c:\zap.bat copy "CD " shell into zap.bat cd >>c:\zap.bat add current directory "CD C:\NOW\HERE" cd where\ever\you\want\to\go now change directories freely yourprog and execute your programs c:\zap.bat now go back to original directory del c:\zap.bat and delete temp file NOTE: you do not have to place CDMSG.BAT and ZAP.BAT in your root directory, but you must always place it in the same directory and specify a full path name -- ^ ^ Glen Shires, Intel, Santa Clara, Ca. O O Usenet: {ucbvax!amd,pur-ee,hplabs}!intelca!glen > ARPA: "amd!intelca!glen"@BERKELEY \-/ --- stay mellow
g-tsang@gumby.UUCP (Michael H. Tsang) (02/03/86)
In responding to the question of "where are you after a batch file?", I have written the following programs in Turbo Pascal. They are "pushd.pas" and "popd.pas". These programs simulate the corresponding pushd and popd commands in UNIX. It requires you to set up a file named "dirstack" in the directory "c:\tmp", but it can be changed by changing the constant StackFileName. I would like to see somebody rewriting these programs in assembly in order to reduce the program size (about 11K for each .COM file now). A sample batch file showing how to use these programs are given below: (suppose your applica- tion program is c:\tools\wordstar\ws.com) File: ws.bat echo off pushd c:\tools\wordstar ws popd echo on ------------------------------CUT HERE------------------------- {$G512,P512} program Pushd(input, output); const ProgramName = 'pushd'; Version = '[v1.01 (c) 2.2.86]'; StackFileName = 'c:\tmp\dirstack'; type Str255 = string[255]; StackPtr = ^StackRec; StackRec = record Path: Str255; Next: StackPtr end; var StackFile: text; StkTop, StkBot: StackPtr; Depth: integer; Dirty: boolean; procedure BuildStack; begin new(StkTop); StkBot := StkTop; GetDir(0, StkTop^.Path); Depth := 0; assign(StackFile, StackFileName); reset(StackFile); while not eof(StackFile) do begin new(StkBot^.Next); StkBot := StkBot^.Next; readln(StackFile, StkBot^.Path); Depth := Depth + 1 end; StkBot^.Next := nil; close(StackFile) end; { BuildStack } procedure SwapStackTop; var NewTop: StackPtr; begin BuildStack; if Depth < 1 then writeln(ProgramName, ': No other directory') else begin NewTop := StkTop^.Next; StkTop^.Next := NewTop^.Next; NewTop^.Next := StkTop; StkTop := NewTop; Dirty := true end end; { SwapStackTop } procedure RotateStack(NumStr: Str255); var Cnt, Num, Result: integer; begin Val(Copy(NumStr, 2, Length(NumStr)-1), Num, Result); if (Result <> 0) or (Num <= 0) then writeln(ProgramName, ': ', NumStr, ': No such file or directory') else begin BuildStack; if Num > Depth then writeln(ProgramName, ': Directory stack not that deep') else begin StkBot^.Next := StkTop; for Cnt := 1 to Num do begin StkTop := StkTop^.Next; StkBot := StkBot^.Next end; StkBot^.Next := nil; Dirty := true end end end; { RotateStack } procedure PushStack(ArgStr: Str255); var StkNode: StackPtr; begin BuildStack; new(StkNode); StkNode^.Path := ArgStr; StkNode^.Next := StkTop; StkTop := StkNode; Dirty := true end; { PushStack } procedure SaveStack; begin {$I-} ChDir(StkTop^.Path); {$I+} if IOResult <> 0 then writeln(ProgramName, ': ', StkTop^.Path, ': No such file or directory') else begin assign(StackFile, StackFileName); rewrite(StackFile); StkTop := StkTop^.Next; while StkTop <> nil do begin writeln(StackFile, StkTop^.Path); StkTop := StkTop^.Next end; close(StackFile) end end; { SaveStack } var Argc: integer; ArgStr: Str255; begin { Pushd } Argc := ParamCount; if Argc > 1 then writeln('Usage: ', ProgramName, ' [pathname | +n | -v]') else begin Dirty := false; if Argc = 0 then SwapStackTop else begin ArgStr := ParamStr(1); if ArgStr = '-v' then writeln(ProgramName, ': ', Version) else if ArgStr[1] = '+' then RotateStack(ArgStr) else PushStack(ArgStr) end; if Dirty then SaveStack end end. { Pushd } -------------------------CUT HERE-------------------------- {$G512,P512} program Popd(input, output); const ProgramName = 'popd'; Version = '[v1.01 (c) 2.2.86]'; StackFileName = 'c:\tmp\dirstack'; type Str255 = string[255]; StackPtr = ^StackRec; StackRec = record Path: Str255; Next: StackPtr end; var StackFile: text; StkTop, StkBot: StackPtr; Depth: integer; Dirty: boolean; procedure BuildStack; begin new(StkTop); StkBot := StkTop; GetDir(0, StkTop^.Path); Depth := 0; assign(StackFile, StackFileName); reset(StackFile); while not eof(StackFile) do begin new(StkBot^.Next); StkBot := StkBot^.Next; readln(StackFile, StkBot^.Path); Depth := Depth + 1 end; StkBot^.Next := nil; close(StackFile) end; { BuildStack } procedure PopStack; var PathStr: Str255; StkNode: StackPtr; begin BuildStack; if Depth < 1 then writeln(ProgramName, ': Directory stack empty') else begin StkTop := StkTop^.Next; Dirty := true end end; { PopStack } procedure DeleteStack(NumStr: Str255); var TmpPtr: StackPtr; Cnt, Num, Result: integer; begin Val(Copy(NumStr, 2, Length(NumStr)-1), Num, Result); if (Result <> 0) or (Num <= 0) then writeln(ProgramName, ': ', NumStr, ': Bad directory') else begin BuildStack; if Num > Depth then writeln(ProgramName, ': Directory stack not that deep') else begin TmpPtr := StkTop; for Cnt := 1 to Num-1 do TmpPtr := TmpPtr^.Next; TmpPtr^.Next := TmpPtr^.Next^.Next; Dirty := true end end end; { DeleteStack } procedure SaveStack; begin {$I-} ChDir(StkTop^.Path); {$I+} if IOResult <> 0 then writeln(ProgramName, ': ', StkTop^.Path, ': Bad directory') else begin assign(StackFile, StackFileName); rewrite(StackFile); StkTop := StkTop^.Next; while StkTop <> nil do begin writeln(StackFile, StkTop^.Path); StkTop := StkTop^.Next end; close(StackFile) end end; { SaveStack } var Argc: integer; ArgStr: Str255; begin { Popd } Argc := ParamCount; if Argc > 1 then writeln('Usage: ', ProgramName, ' [+n | -v]') else begin Dirty := false; if Argc = 0 then PopStack else begin ArgStr := ParamStr(1); if ArgStr = '-v' then writeln(ProgramName, ': ', Version) else if ArgStr[1] = '+' then DeleteStack(ArgStr) else writeln(ProgramName, ': ', ArgStr, ': Bad directory') end; if Dirty then SaveStack end end. { Popd } --------------------------CUT HERE---------------------------- Have fun with these programs. Mike Tsang
broehl@watdcsu.UUCP (Bernie Roehl) (02/05/86)
In article <51@gumby.UUCP> g-tsang@gumby.UUCP (Michael H. Tsang) writes: > > In responding to the question of "where are you after a batch file?", I >have written the following programs in Turbo Pascal. They are "pushd.pas" and >"popd.pas". These programs simulate the corresponding pushd and popd commands >in UNIX. It requires you to set up a file named "dirstack" in the directory >"c:\tmp", but it can be changed by changing the constant StackFileName. First, thanks to Michael Tsang for taking time to write and post these programs. Now, a suggestion: why doesn't somebody write a program that either (a) keeps the directory stack in the environment, instead of having to have a writeable file sitting around on disk and doing disk accesses for directory pushing/popping? Another approach would be a tiny program that gets the current directory and then executes a fresh copy of command.com; when you exit, the program would restore the current directory and then exit. This avoids scratch files and large environments, but takes up a few K of extra ram for the fresh copy of the command interpreter. Just some ideas...
connery@bnrmtv.UUCP (Glenn Connery) (02/09/86)
> ... > > Now, a suggestion: why doesn't somebody write a program that either (a) keeps > the directory stack in the environment, instead of having to have a writeable > file sitting around on disk and doing disk accesses for directory > pushing/popping? Another approach would be a tiny program that gets the > current directory and then executes a fresh copy of command.com; when you > exit, the program would restore the current directory and then exit. This > avoids scratch files and large environments, but takes up a few K of extra > ram for the fresh copy of the command interpreter. > > Just some ideas... The latter is what COMMAND /c should be doing anyway, but I really don't want to waste the time or memory on this, as well as the fact that it would mean multiple batch files where I only wanted one. Also, there are problems with doing certain things this way--you can't pass back errorlevel across such things for example. The former is a great idea, but I've never seen anybody propose a method for handling this. You have to remember that when a program is run by DOS, it is given a COPY of the original environment. You can write a program to modify that environment (though it is still unclear how you know how much space that environment has been allocated, as opposed to how much it is using). You could even use Microsoft C 3.0's builtin functions for doing this. But when your program exits the old environment will be restored with none of your changes. If you were willing to write a shell or something you could do this by running the program as an overlay instead, but this seems like it would be tricky, and wouldn't be portable across multiple versions of DOS. As well, if you were going to write a shell for this specific purpose, you might as well just provide the capabilities that DOS left out directly rather than doing it this way (variables, pushd/popd). If anybody has any information on this subject I'd be real interested to hear it. ...Glenn
hamilton@uiucuxc.CSO.UIUC.EDU (02/12/86)
>> Now, a suggestion: why doesn't somebody write a program that either (a) keeps >> the directory stack in the environment, instead of having to have a writeable >> file sitting around on disk and doing disk accesses for directory >> pushing/popping? > >[this] is a great idea, but I've never seen anybody propose a method >for handling this. You have to remember that when a program is run by >DOS, it is given a COPY of the original environment. You can write a >program to modify that environment (though it is still unclear how you >know how much space that environment has been allocated, as opposed to how >much it is using). You could even use Microsoft C 3.0's builtin functions >for doing this. But when your program exits the old environment will be >restored with none of your changes. well, there is an ugly way to do this (modify command.com's copy of the environment). i did some exploring some time back, and figured how to scan memory and recognize memory control blocks. you can also find out where command.com is (the para is all you want) from one of the several pointers to it in your psp. the first memory control block before the one containing command.com (if i remember right) is the one containing command.com's environment (i _said_ it was ugly). the control block tells you how much space is allocated to the environment, and you parse to find how much was used. i wrote a little program using a scan for control blocks to produce a map of allocated memory; the result is slightly useful as a substitute for a "ps". wayne hamilton U of Il and US Army Corps of Engineers CERL UUCP: {ihnp4,pur-ee,convex}!uiucdcs!uiucuxc!hamilton ARPA: hamilton%uiucuxc@a.cs.uiuc.edu USMail: Box 476, Urbana, IL 61801 CSNET: hamilton%uiucuxc@uiuc.csnet Phone: (217)333-8703