21

I'm looking for some historical context, valid for both any Windows prompt but my guess would be that the behaviour can be seen at least from MS-DOS, if not earlier.

It feels counter-intuitive to me to have a batch file just ignore the rest of the content if I invoke another bat file without using CALL.

Is there a documented reason why they system was designed this way?

If no documented reason can be found, I'm settling for an educated guess from someone more familiar with DOS than me, which I suspect is most of the people around here :)

7
  • 14
    CALL was introduced in MS-DOS 3.3 so before then that was just the way it was. You could use COMMAND /C to run another batch file and return but after returning you would not get back any changes to environment variables etc so of limited use.
    – Brian
    Mar 29 at 17:16
  • 18
    'Counter-intuitive' meets 'limited system resources'. Mar 29 at 17:23
  • 1
    The straightforward implementation for batch processing is to just read the input for the command processor from a file instead of the keyboard/stdin/whatever. In this implementation, whenever you start batch processing from a second file, processing the first file obviously stops. To have nested batch processing, you need a call stack. IIRC correctly already CP/M worked this way. (And I don't think this design decision is documented somewhere, the reason is just "we don't have permanent memory to implement a call stack")
    – dirkt
    Mar 29 at 17:45
  • 5
    @dirkt No, CP/M could not nest batch execution. At least not the 8 bit variants prior to MS-DOS. The genuine system could only execute a single file with the fixed name $$$.SUB. Which was in turn modified by deleting each line executed - until the file was empty and deleted in total. Very Byzantine. There might have been 3rd party CCP replacements with better batch handling, like ZEX and ZCPR.
    – Raffzahn
    Mar 29 at 19:26
  • 6
    @Raffzahn I meant "CP/M already worked by just having the command processor execute a single file, no nesting", not "CP/M already implemented a call stack". Sorry, bad phrasing, and I can't edit it now...
    – dirkt
    Mar 30 at 4:02

1 Answer 1

37

It feel counter-intuitive to me to have a batch file just ignore the rest of the content it I invoke another bat file without using call.

Is there a documented reason why they system was designed this way?

Simply resources. Keep in mind, DOS was created to run on machines with less than 64 KiB of RAM (*1), so everything was kept tight (*2).

A Command.com has only provisions for running a single batch file - that is it has only one buffer to hold one file name and a position within(*3). Whenever a command was found to be a batch file, the name entry was replaced by the newly found one and the position counter reset.

To allow nested execution of batch files it would need to maintain a stack of buffers, which would take up much wanted space. Nested execution was introduced with DOS 3.3.

If needed the same could be reached by opening a sub-Shell by executing another Command.com, which would bring its own buffer and thus being able to run another batch file:

COMMAND /C another.bat

When that batch file ended the sub-shell would as well quit and return execution to the previous one. This was also way in line with the idea to develop DOS toward a Unix like environment.

Except the additionally needed resources for the new shell were a quite negative effect. Under PC-DOS 2.0 each level did eat up about 3 KiB:

enter image description here

(Disk statistics removed to reduce size)

Thus DOS 3.3 added a way to execute a nested job by 'calling' it. Introduction of the new CALL keyword was needed to avoid screwing existing batch jobs based on chaining.


*1 - Minimum RAM for DOS 1 is 32 KiB, 48 for DOS 2.x and 64 for DOS 3.x. though, useful operation might need a bit more :))

*2 - In fact, having full batch processing as a build in feature was already a step forward from CP/M where batch files had to be prepared by external SUBMIT command, followed by a system reset after which CCP expected the batch file on the A drive, all of that working somewhat like a AUTOEXEC.BAT :))

Further to allow batch programs to receive user input another program, XSUB had to be started by the batch file. So yes, even the modest features of DOS 1.x batch files were a huge step forward.

*3 - To reserve resources Command even closed a batch file when a program was executed and (re)opened it afterwards, thus freeing an entry in the System File Table (At least since DOS 2.0).

13
  • 3
    @WolframRösler Unix was nearly useless on a floppy disk based system. Needed a fast disk for swap to make the nesting work without taking all day.
    – John Doty
    Mar 30 at 16:35
  • 4
    @WolframRösler Erm, you may want to check again what limited resources means. The minimum requirement for a V5 in 1974 was 40 KiWord (80 KiB) just to boot - and V5 was far from what people today would consider Unix today (14 char filenames). But to compare on the same machine, Xenix-PC (Full V7 of 1984) needed a minimum of 512KiB and a hard disk. Even the single user 1984 PC/IX (SIII) needs 256 KiB and a hard disk as minimum. Neither exactly usable for a PC with a single floppy and <64 KiB RAM.
    – Raffzahn
    Mar 30 at 16:38
  • 2
    Using the approach of `COMMAND /C <another.bat> how much of your RAM does that take? I guess I'm asking what the runtime footprint of that was?
    – davidbak
    Mar 30 at 17:47
  • 2
    @davidbak Under PC-DOS 2.0 a bit more than 3 KiB per level.
    – Raffzahn
    Mar 30 at 19:43
  • 3
    The original UNIX did not have stacking either. A single process was created per terminal and there was no fork, only exec to chain to another program with no return. An exit was identical to exec'ing the shell back into memory fresh.
    – paxdiablo
    Mar 30 at 23:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .