Why are there both TMP and TEMP environment variables? (2015)

Why are there both TMP and TEMP environment variables? (2015)

为什么会有 TMP 和 TEMP 两个环境变量?(2015)

If you snoop around your environment variables, you may notice that there are two variables that propose to specify the location of temporary files. There is one called TMP and another called TEMP. Why two? And if they disagree, then who’s right? 如果你仔细查看自己的环境变量,可能会注意到有两个变量都用于指定临时文件的存放位置。一个叫 TMP,另一个叫 TEMP。为什么会有两个?如果它们指向的路径不同,到底该听谁的?

Rewind to 1973. The operating system common on microcomputers was CP/M. The CP/M operating system had no environment variables. That sounds like a strange place to start a discussion of environment variables, but it’s actually important. Since it had no environment variables, there was consequently neither a TMP nor a TEMP environment variable. 时间回到 1973 年。当时微型计算机上通用的操作系统是 CP/M。CP/M 操作系统没有环境变量。从这里开始讨论环境变量听起来有些奇怪,但这其实很重要。由于没有环境变量,自然也就没有 TMP 或 TEMP 变量。

If you wanted to configure a program to specify where to put its temporary files, you needed to do some sort of program-specific configuration, like patching a byte in the executable to indicate the drive letter where temporary files should be stored. (My recollection is that most CP/M programs were configured via patching. At least that’s how I configured them. I remember my WordStar manual coming with details about which bytes to patch to do what. There was also a few dozen bytes of patch space set aside for you to write your own subroutines, in case you needed to add custom support for your printer. I did this to add an “Is printer ready to accept another character?” function, which allowed for smoother background printing.) 如果你想配置程序以指定临时文件的存放位置,必须进行某种程序特定的配置,例如修改可执行文件中的一个字节,来指定存放临时文件的驱动器盘符。(我的记忆中,大多数 CP/M 程序都是通过这种“打补丁”的方式配置的。至少我是这么做的。我记得我的 WordStar 手册里详细说明了修改哪些字节可以实现什么功能。手册还预留了几十个字节的补丁空间,供你编写自己的子程序,以备需要为打印机添加自定义支持时使用。我就曾用它添加了一个“打印机是否准备好接收下一个字符?”的功能,这让后台打印变得更加顺畅。)

Move forward to 1981. The 8086 processor and the MS-DOS operating system arrived on the scene. The design of both the 8086 processor and the MS-DOS operating system were strongly inspired by CP/M, so much so that it was the primary design goal that it be possible to take your CP/M program written for the 8080 processor and machine-translate it into an MS-DOS program written for the 8086 processor. 时间来到 1981 年。8086 处理器和 MS-DOS 操作系统登场了。8086 处理器和 MS-DOS 的设计深受 CP/M 的影响,以至于它们的主要设计目标之一,就是能够将为 8080 处理器编写的 CP/M 程序通过机器翻译转换为运行在 8086 处理器上的 MS-DOS 程序。

Mind you, the translator assumed that you didn’t play any sneaky tricks like self-modifying code, jumping into the middle of an instruction, or using code as data, but if you played honest, the translator would convert your program. (The goal of allowing machine-translation of code written for the 8080 processor into code written for the 8086 processor helps to explain some of the quirks of the 8086 instruction set. For example, the H and L registers on the 8080 map to the BH and BL registers on the 8086, and on the 8080, the only register that you could use to access a computed address was HL. This is why of the four basic registers AX, BX, CX, and DX on the 8086, the only one that you can use to access memory is BX.) 当然,翻译器假设你没有耍什么小聪明,比如使用自修改代码、跳入指令中间执行,或者将代码当作数据处理。只要你规规矩矩,翻译器就能转换你的程序。(这种将 8080 代码机器翻译为 8086 代码的目标,解释了 8086 指令集的一些怪癖。例如,8080 上的 H 和 L 寄存器映射到 8086 上的 BH 和 BL 寄存器;而在 8080 上,唯一能用于访问计算地址的寄存器是 HL。这就是为什么在 8086 的四个基本寄存器 AX、BX、CX 和 DX 中,只有 BX 能用于访问内存。)

One of the things that MS-DOS added beyond compatibility with CP/M was environment variables. Since no existing CP/M programs used environment variables, none of the first batch of programs for MS-DOS used them either, since the first programs for MS-DOS were all ported from CP/M. Sure, you could set a TEMP or TMP environment variable, but nobody would pay attention to it. MS-DOS 在兼容 CP/M 的基础上增加的一项功能就是环境变量。由于现有的 CP/M 程序都不使用环境变量,MS-DOS 的第一批程序也都不使用它们,因为这些程序都是从 CP/M 移植过来的。当然,你可以设置 TEMP 或 TMP 环境变量,但没人会理会它。

Over time, programs were written with MS-DOS as their primary target, and they started to realize that they could use environment variables as a way to store configuration data. In the ensuing chaos of the marketplace, two environment variables emerged as the front-runners for specifying where temporary files should go: TEMP and TMP. 随着时间的推移,程序开始以 MS-DOS 为主要目标进行开发,开发者们意识到可以使用环境变量来存储配置数据。在随后的市场混乱中,两个环境变量脱颖而出,成为指定临时文件存放位置的首选:TEMP 和 TMP。

MS-DOS 2.0 introduced the ability to pipe the output of one program as the input of another. Since MS-DOS was a single-tasking operating system, this was simulated by redirecting the first program’s output to a temporary file and running it to completion, then running the second program with its input redirected from that temporary file. Now all of a sudden, MS-DOS needed a location to create temporary files! For whatever reason, the authors of MS-DOS chose to use the TEMP variable to control where these temporary files were created. MS-DOS 2.0 引入了将一个程序的输出作为另一个程序输入的功能(管道)。由于 MS-DOS 是单任务操作系统,这是通过将第一个程序的输出重定向到一个临时文件并运行完毕,然后再运行第二个程序并从该临时文件读取输入来模拟的。突然之间,MS-DOS 需要一个地方来创建临时文件了!出于某种原因,MS-DOS 的作者选择了使用 TEMP 变量来控制这些临时文件的创建位置。

Mind you, the fact that COMMAND.COM chose to go with TEMP didn’t affect the fact that other programs could use either TEMP or TMP, depending on the mood of their original author. Many programs tried to appease both sides of the conflict by checking for both, and it was up to the mood of the original author which one it checked first. For example, the old DISKCOPY and EDIT programs would look for TEMP before looking for TMP. 需要注意的是,COMMAND.COM 选择使用 TEMP,并不影响其他程序根据其作者的喜好选择使用 TEMP 或 TMP。许多程序为了平息这种冲突,会同时检查这两个变量,至于先检查哪一个,完全取决于作者的心情。例如,旧版的 DISKCOPY 和 EDIT 程序会先查找 TEMP,然后再查找 TMP。

Windows went through a similar exercise, but for whatever reason, the original authors of the Get­Temp­File­Name function chose to look for TMP before looking for TEMP. The result of all this is that the directory used for temporary files by any particular program is at the discretion of that program, Windows programs are likely to use the Get­Temp­File­Name function to create their temporary files, in which case they will prefer to use TMP. Windows 也经历了类似的过程,但出于某种原因,GetTempFileName 函数的原始作者选择了先查找 TMP,再查找 TEMP。这一切的结果是,任何特定程序使用的临时文件目录都由该程序自行决定。Windows 程序很可能会使用 GetTempFileName 函数来创建临时文件,在这种情况下,它们会优先使用 TMP。

When you go to the Environment Variables configuration dialog, you’ll still see both variables there, TMP and TEMP, still duking it out for your attention. It’s like Adidas versus Puma, geek version. 当你打开环境变量配置对话框时,你仍然会看到 TMP 和 TEMP 这两个变量,它们依然在争夺你的关注。这就像是极客版的阿迪达斯与彪马之争。