在 FreeDOS 上使用 BAT 文件自动执行任务
FreeDOS 批处理

> 
> FreeDOS 下批处理文件的实用指南。
> 
> 
> 


![](/data/attachment/album/202111/10/104345whfjagaahm9nb2j3.jpg "Tips and gears turning")


即使你以前没有使用过 DOS，你也可能知道它的命令行 shell，即 `COMMAND.COM`。它已经成为 DOS 的同义词，FreeDOS 为此也实现了一个类似的 shell，称为 “FreeCOM”，但也命名为 `COMMAND.COM`，就像在其他 DOS 系统上一样。


但是 FreeCOM shell 可以做的不仅仅是为你提供一个命令行提示符让你在其中运行命令，如果你需要在 FreeDOS 上自动执行任务，你可以使用 *批处理文件*，也称为 “BAT 文件”，因为这些脚本使用 `.BAT` 扩展名。


批处理文件可能比你在 Linux 编写的脚本要简单得多。因为在很久以前，这个功能最初被添加到 DOS 时，它是为了让 DOS 用户“批量处理”某些命令。它的条件分支没有太大的灵活性，也不支持更高级的功能，例如算术扩展、标准输出和错误消息的重定向、后台进程、测试、循环（这项支持）和 Linux 脚本中常见的其他结构。


本文是 FreeDOS 下批处理文件的实用指南。记住通过用百分号（`%`）包裹变量名称来引用环境变量，例如 `%PATH%`。但是，请注意，由于历史原因，`FOR` 循环的构造略有不同。


### 打印输出


批处理文件可能需要向用户打印消息，让用户知道发生了什么。使用 `ECHO` 语句打印消息。例如，一个批处理文件可能使用以下语句表明它已完成了任务：



```
ECHO Done

```

`ECHO` 语句不需要引号。FreeCOM `ECHO` 语句不会以任何特殊方式处理引号，它会像普通文本一样打印它们。


通常，FreeDOS 在执行批处理文件时会打印每一行。这在一个非常短的批处理文件中通常不是问题，它只为用户定义了几个环境变量。但是对于执行更多工作的较长批处理文件而言，批处理行的这种一直显示可能会变得很麻烦。要阻止此输出，在 `ECHO` 语句中使用 `OFF` 关键字，如下所示：



```
ECHO OFF

```

使用 `ON` 关键字在 FreeDOS 运行时恢复显示批处理行。



```
ECHO ON

```

大多数批处理文件在第一行包含一个 `ECHO OFF` 语句，以阻止消息，但是 shell 在执行语句时仍然会在屏幕上打印 `ECHO OFF`。为了隐藏该语句，批处理文件通常在前面使用 `@` 符号。这样，任何以这个特殊字符开头的行都不会打印，即使打开了 `ECHO`。



```
@ECHO OFF

```

### 注释


编写较长批处理文件时，大多数程序员都喜欢使用 *注释* 来提醒自己这个批处理文件的用途。在批处理文件中注释，使用 `REM`（remark）关键字。`REM` 之后的任何内容都会被 FreeCOM shell 忽略。



```
@ECHO OFF
REM This is a comment

```

### 执行“辅助”批处理文件


通常，FreeCOM 一次只运行一个批处理文件。但是，你可能需要使用另一个批处理文件来执行其他操作，例如为多个批处理文件设置公共环境变量。


如果你从"正在运行"的批处理文件中直接调用第二个批处理文件，FreeCOM 将完全切换到第二个批处理文件，并停止处理第一个。要改为在第一个批处理文件“内部”运行第二个批处理文件，你需要告诉 FreeDOS shell 使用 `CALL` 关键字去 *调用* 第二个批处理文件。



```
@ECHO OFF
CALL SETENV.BAT

```

### 条件分支


批处理文件确实支持使用 `IF` 语句的简单条件分支。它有三种基本形式：


1. 测试上一条命令的返回状态
2. 测试一个变量是否等于一个值
3. 测试文件是否存在


`IF` 语句的一个常见用途是测试程序是否成功返回。如果它们正常运行，大多数程序将返回零值，或者在出现错误时返回一些其他值。在 DOS 中，这称为 *错误级别*，这是 `IF` 测试的特例。


测试名为 `MYPROG` 的程序是否成功退出，实际上是检查程序是否返回“零”。使用 `ERRORLEVEL` 关键字来测试特定值。例如：



```
@ECHO OFF
MYPROG
IF ERRORLEVEL 0 ECHO Success

```

使用 `ERRORLEVEL` 测试错误级别是检查程序退出状态的笨拙方法。检查 DOS 程序的不同返回值，更有用的方法是使用 FreeDOS 为你定义的特殊变量，称为 `ERRORLEVEL`。它存储了最近执行程序的错误级别，然后你可以使用 `==` 测试不同的值。


你可以使用 `==` 和 `IF` 语句来测试变量是否等于某个值。就像一些编程语言，你可以使用 `==` 直接比较两个值。通常，在一侧引用一个环境变量，在另一侧引用一个值，但你也可以比较两个变量的值以查看它们是否相同。例如，你可以使用此批处理文件重写上面的 `ERRORLEVEL` 代码：



```
@ECHO OFF
MYPROG
IF %ERRORLEVEL%==0 ECHO Success

```

`IF` 语句的另一个常见用途是测试文件是否存在，如果存在则采取操作。你可以使用 `EXIST` 关键字来测试。例如，要删除名为 `TEMP.DAT` 的临时文件，你可以在批处理文件中使用以下行：



```
@ECHO OFF
IF EXIST TEMP.DAT DEL TEMP.DAT

```

对于任何 `IF` 语句，你都可以使用 `NOT` 关键字来 *否定* 测试。在文件 *不* 存在时打印消息，你可以这样写：



```
@ECHO OFF
IF NOT EXIST TEMP.DAT ECHO No file

```

### 分支执行


利用 `IF` 测试的一种方法是跳转到批处理文件中完全不同的部分，这取决于 `IF` 测试的结果。在最简单的情况下，如果一个关键命令失败，你可能希望跳到批处理文件的末尾。或者，如果某些环境变量设置不正确，你可能想要执行其他语句。


你可以使用 `GOTO` 指令跳转到批处理文件的其他部分。它会跳转到批处理文件中称为 *标签* 的特定行。注意，这是一个严格的 “go-to” 跳转：批处理文件执行将在新标签处启动。


假设程序需要一个现有的空文件来存储临时数据，如果文件不存在，则需要在运行程序之前创建一个文件。你可以将这些动作添加到批处理文件中，这样你的程序始终有一个临时文件可供使用：



```
@ECHO OFF
IF EXIST temp.dat GOTO prog
ECHO Creating temp file...
TOUCH temp.dat
:prog
ECHO Running the program...
MYPROG

```

当然，这是一个非常简单的例子。对于这种情况，你可以重写批处理文件，将创建临时文件作为 `IF` 语句的一部分：



```
@ECHO OFF
IF NOT EXIST temp.dat TOUCH temp.dat
ECHO Running the program...
MYPROG

```

### 迭代


如果你需要对一组文件执行相同的任务怎么办？你可以使用 `FOR` 循环 *迭代* 一组文件。这是一个单行循环，每次使用不同的文件运行单个命令。


`FOR` 循环对迭代变量使用一种特殊的语法，它的用法与其他 DOS 环境变量不同。要循环编辑一组文本文件，可以使用以下语句：（LCTT 译注：原文此处写错了，少写了一个 `%`）



```
@ECHO OFF
FOR %%F IN (*.TXT) DO EDIT %%F

```

注意，如果在命令行中运行此循环，而不是在批处理文件中，那么迭代变量仅需要指定一个百分号（`%`）：



```
C:\> FOR %F IN (*.TXT) DO EDIT %F

```

### 命令行处理


在运行批处理文件时，FreeDOS 提供了一种简单的方法来检测用户可能提供的命令行选项。FreeDOS 解析命令行输入，并将前九个选项存储在特殊变量 `%1`、`%2` ..... 等中，直到 `%9`。注意，无法通过这种方式直接访问第十一个（及之后）选项。特殊变量 `%0` 存储批处理文件的名称。


如果你的批处理文件需要处理 9 个以上的选项，你可以使用 `SHIFT` 语句移除第一个选项，并将每个选项向下 *移动* 一个值。所以第二个选项变成了 `%1`，第十个选项变成了 `%9`。


大多数批处理文件只需要移动一个值。但是，如果你需要以其他增量进行移位，可以将参数提供给 `SHIFT` 语句。例如：



```
SHIFT 2

```

下面是一个简单的批处理文件，演示了移位操作：



```
@ECHO OFF
ECHO %1 %2 %3 %4 %5 %6 %7 %8 %9
ECHO Shift by one ..
SHIFT 1
ECHO %1 %2 %3 %4 %5 %6 %7 %8 %9

```

执行带有十个选项的批处理文件显示了 `SHIFT` 语句如何重新排列命令行选项，因此批处理文件现在可以用 `%9` 访问第十个参数：



```
C:\SRC>args 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9
Shift by one ..
2 3 4 5 6 7 8 9 10
C:\SRC>

```



---


via: <https://opensource.com/article/21/6/automate-tasks-bat-files-freedos>


作者：[Jim Hall](https://opensource.com/users/jim-hall) 选题：[lujun9972](https://github.com/lujun9972) 译者：[MjSeven](https://github.com/MjSeven) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Even if you haven't used DOS before, you are probably aware of its command-line shell, named simply `COMMAND.COM`

. The `COMMAND.COM`

shell has become synonymous with DOS, and so it's no surprise that FreeDOS also implements a similar shell called "FreeCOM"—but named `COMMAND.COM`

just as on other DOS systems.

But the FreeCOM shell can do more than just provide a command-line prompt where you run commands. If you need to automate tasks on FreeDOS, you can do that using *batch files*, also called "BAT files" because these scripts use the `.BAT`

extension.

Batch files are much simpler than scripts you might write on Linux. That's because when this feature was originally added to DOS, long ago, it was meant as a way for DOS users to "batch up" certain commands. There's not much flexibility for conditional branching, and batch files do not support more advanced features such as arithmetic expansion, separate redirection for standard output vs error messages, background processes, tests, loops, and other scripting structures that are common in Linux scripts.

Here's a helpful guide to batch files under FreeDOS. Remember to reference environment variables by wrapping the variable name with percent signs (`%`

) such as `%PATH%`

. However, note that `FOR`

loops use a slightly different construct for historical reasons.

## Printing output

Your batch file might need to print messages to the user, to let them know what's going on. Use the `ECHO`

statement to print messages. For example, a batch file might indicate it is done with a task with this statement:

`ECHO Done`


You don't need quotes in the `ECHO`

statement. The FreeCOM `ECHO`

statement will not treat quotes in any special way and will print them just like regular text.

Normally, FreeDOS prints out every line in the batch file as it executes them. This is usually not a problem in a very short batch file that only defines a few environment variables for the user. But for longer batch files that do more work, this constant display of the batch lines can become bothersome. To suppress this output, use the `OFF`

keyword to the `ECHO`

statement, as:

`ECHO OFF`


To resume displaying the batch lines as FreeDOS runs them, use the `ON`

keyword instead:

`ECHO ON`


Most batch files include an `ECHO OFF`

statement on the first line, to suppress messages. But the shell will still print `ECHO OFF`

to the screen as it executes that statement. To hide that message, batch files often use an at sign (`@`

) in front. This special character at the start of any line in a batch file suppresses printing that line, even if `ECHO`

is turned on.

`@ECHO OFF`


## Comments

When writing any long batch file, most programmers prefer to use *comments* to remind themselves about what the batch file is meant to do. To enter a comment in a batch file, use the `REM`

(for *remark*) keyword. Anything after `REM`

gets ignored by the FreeCOM shell.

```
@ECHO OFF
REM This is a comment
```


## Executing a "secondary" batch file

Normally, FreeCOM only runs one batch file at a time. However, you might need to use another batch file to do certain things, such as set environment variables that are common across several batch files.

If you simply call the second batch file from a "running" batch file, FreeCOM switches entirely to that second batch file and stops processing the first one. To instead run the second batch file "inside" the first batch file, you need to tell the FreeCOM shell to *call* the second batch file with the `CALL`

keyword.

```
@ECHO OFF
CALL SETENV.BAT
```


## Conditional evaluation


Batch files do support a simple conditional evaluation structure with the `IF`

statement. This has three basic forms:

- Testing the return status of the previous command
- Testing if a variable is equal to a value
- Testing if a file exists

A common use of the `IF`

statement is to test if a program returned successfully to the operating system. Most programs will return a zero value if they completed normally, or some other value in case of an error. In DOS, this is called the *error level* and is a special case to the `IF`

test.

To test if a program called `MYPROG`

exited successfully, you actually want to examine if the program returned a "zero" error level. Use the `ERRORLEVEL`

keyword to test for a specific value, such as:

```
@ECHO OFF
MYPROG
IF ERRORLEVEL 0 ECHO Success
```


Testing the error level with `ERRORLEVEL`

is a clunky way to examine the exit status of a program. A more useful way to examine different possible return codes for a DOS program is with a special variable FreeDOS defines for you, called `ERRORLEVEL`

. This stores the error level of the most recently executed program. You can then test for different values using the `==`

test.

You can test if a variable is equal to a value using the `==`

test with the `IF`

statement. Like some programming languages, you use `==`

to directly compare two values. Usually, you will reference an environment variable on one side and a value on the other, but you could also compare the values of two variables to see if they are the same. For example, you could rewrite the above `ERRORLEVEL`

code with this batch file:

```
@ECHO OFF
MYPROG
IF %ERRORLEVEL%==0 ECHO Success
```


And another common use of the `IF`

statement is to test if a file exists, and take action if so. You can test for a file with the `EXIST`

keyword. For example, to delete a temporary file called `TEMP.DAT`

, you might use this line in your batch file:

```
@ECHO OFF
IF EXIST TEMP.DAT DEL TEMP.DAT
```


With any of the `IF`

statements, you can use the `NOT`

keyword to *negate* a test. To print a message if a file *does not* exist, you could write:

```
@ECHO OFF
IF NOT EXIST TEMP.DAT ECHO No file
```


## Branched execution

One way to leverage the `IF`

test is to jump to an entirely different part of the batch file, depending on the outcome of a previous test. In the simplest case, you might want to skip to the end of the batch file if a key command fails. Or you might want to execute other statements if certain environment variables are not set up correctly.

You can skip around to different parts of a batch file using the `GOTO`

instruction. This jumps to a specific line, called a *label*, in the batch file. Note that this is a strict "go-to" jump; batch file execution picks up at the new label.

Let's say a program needed an existing empty file to store temporary data. If the file did not exist, you would need to create a file before running the program. You might add these lines to a batch file, so your program always has a temporary file to work with:

```
@ECHO OFF
IF EXIST temp.dat GOTO prog
ECHO Creating temp file...
TOUCH temp.dat
:prog
ECHO Running the program...
MYPROG
```


Of course, this is a very simple example. For this one case, you might instead rewrite the batch file to create the temporary file as part of the `IF`

statement:

```
@ECHO OFF
IF NOT EXIST temp.dat TOUCH temp.dat
ECHO Running the program...
MYPROG
```


## Iteration

What if you need to perform the same task over a set of files? You can *iterate* over a set of files with the `FOR`

loop. This is a one-line loop that runs a single command with a different file each time.

The `FOR`

loop uses a special syntax for the iteration variable, which is used differently than other DOS environment variables. To loop through a set of text files so you can edit each one, in turn, use this statement in your batch file:

```
@ECHO OFF
FOR %%F IN (*.TXT) DO EDIT %%F
```


Note that the iteration variable is specified with only one percent sign (`%`

) if you run this loop at the command line, without a batch file:

`C:\> FOR %F IN (*.TXT) DO EDIT %F`


## Command-line processing

FreeDOS provides a simple method to evaluate any command-line options the user might have provided when running batch files. FreeDOS parses the command line, and stores the first nine batch file options in the special variables `%1`

, `%2`

, .. and so on until `%9`

. Notice that the eleventh option (and beyond) are not directly accessible in this way. (The special variable `%0`

stores the name of the batch file.)

If your batch file needs to process more than nine options, you can use the `SHIFT`

statement to remove the first option and *shift* every option down by one value. So the second option becomes `%1`

, and the tenth option becomes `%9`

.

Most batch files need to shift by one value. But if you need to shift by some other increment, you can provide that parameter to the `SHIFT`

statement, such as:

`SHIFT 2`


Here's a simple batch file that demonstrates shifting by one:

```
@ECHO OFF
ECHO %1 %2 %3 %4 %5 %6 %7 %8 %9
ECHO Shift by one ..
SHIFT 1
ECHO %1 %2 %3 %4 %5 %6 %7 %8 %9
```


Executing this batch file with ten arguments shows how the `SHIFT`

statement reorders the command line options, so the batch file can now access the tenth argument as `%9`

:

```
C:\SRC>args 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9
Shift by one ..
2 3 4 5 6 7 8 9 10
C:\SRC>
```



## Comments are closed.