许多程序员在运行 DOS 的 PC 上学习了脚本编程。即使是功能受限的 DOS 批处理文件语言也允许编写相当强大的脚本和应用程序,尽管它们通常需要大量的变通方法和技巧。有时,仍然需要将旧的 DOS 批处理文件转换为 UNIX shell 脚本。这通常并不困难,因为 DOS 批处理文件操作符只是等效 shell 脚本操作符的一个有限子集。
表 N-1. 批处理文件关键字/变量/操作符及其 shell 等效项
批处理文件操作符 | Shell 脚本等效项 | 含义 |
---|---|---|
% | $ | 命令行参数前缀 |
/ | - | 命令选项标志 |
\ | / | 目录路径分隔符 |
== | = | (等于)字符串比较测试 |
!==! | != | (不等于)字符串比较测试 |
| | | | 管道 |
@ | set+v | 不回显当前命令 |
* | * | 文件名 “通配符” |
> | > | 文件重定向(覆盖) |
>> | >> | 文件重定向(追加) |
< | < | 重定向标准输入 |
%VAR% | $VAR | 环境变量 |
REM | # | 注释 |
NOT | ! | 否定后续测试 |
NUL | /dev/null | 用于埋藏命令输出的 “黑洞” |
ECHO | echo | echo(Bash 中有更多选项) |
ECHO. | echo | echo 空行 |
ECHO OFF | set+v | 不回显后续命令 |
FOR %%VAR IN (LIST) DO | for var in [list]; do | “for” 循环 |
:LABEL | 无(不必要) | 标签 |
GOTO | 无(使用函数) | 跳转到脚本中的另一个位置 |
PAUSE | sleep | 暂停或等待一段时间 |
CHOICE | case 或 select | 菜单选择 |
IF | if | if 测试 |
IF EXISTFILENAME | if [ -e filename ] | 测试文件是否存在 |
IF !%N==! | if [ -z "$N" ] | 如果可替换参数 “N” 不存在 |
CALL | source 或 .(点操作符) | “包含” 另一个脚本 |
COMMAND /C | source 或 .(点操作符) | “包含” 另一个脚本(与 CALL 相同) |
SET | export | 设置环境变量 |
SHIFT | shift | 左移命令行参数列表 |
SGN | -lt 或 -gt | 符号(整数的) |
ERRORLEVEL | $? | 退出状态 |
CON | 标准输入 | “控制台” (标准输入) |
PRN | /dev/lp0 | (通用)打印机设备 |
LPT1 | /dev/lp0 | 第一个打印机设备 |
COM1 | /dev/ttyS0 | 第一个串行端口 |
批处理文件通常包含 DOS 命令。为了将批处理文件转换为 shell 脚本,必须将这些命令转换为其 UNIX 等效项。
表 N-2. DOS 命令及其 UNIX 等效项
DOS 命令 | UNIX 等效项 | 效果 |
---|---|---|
ASSIGN | ln | 链接文件或目录 |
ATTRIB | chmod | 更改文件权限 |
CD | cd | 更改目录 |
CHDIR | cd | 更改目录 |
CLS | clear | 清屏 |
COMP | diff, comm, cmp | 文件比较 |
COPY | cp | 文件复制 |
Ctl-C | Ctl-C | 中断(信号) |
Ctl-Z | Ctl-D | EOF(文件结束符) |
DEL | rm | 删除文件 |
DELTREE | rm -rf | 递归删除目录 |
DIR | ls -l | 目录列表 |
ERASE | rm | 删除文件 |
EXIT | exit | 退出当前进程 |
FC | comm, cmp | 文件比较 |
FIND | grep | 在文件中查找字符串 |
MD | mkdir | 创建目录 |
MKDIR | mkdir | 创建目录 |
MORE | more | 文本文件分页过滤器 |
MOVE | mv | 移动 |
PATH | $PATH | 可执行文件路径 |
REN | mv | rename(移动) |
RENAME | mv | rename(移动) |
RD | rmdir | 删除目录 |
RMDIR | rmdir | 删除目录 |
SORT | sort | 排序文件 |
TIME | date | 显示系统时间 |
TYPE | cat | 输出文件到标准输出 |
XCOPY | cp | (扩展)文件复制 |
![]() | 实际上,所有 UNIX 和 shell 操作符和命令都比其 DOS 和批处理文件对应项具有更多的选项和增强功能。许多 DOS 批处理文件依赖于辅助实用程序,例如 ask.com,它是 read 的功能受限的对应物。 DOS 仅支持文件名 通配符展开 的非常有限且不兼容的子集,仅识别 * 和 ? 字符。 |
将 DOS 批处理文件转换为 shell 脚本通常很简单,并且结果通常比原始文件更易读。
示例 N-1. VIEWDATA.BAT:DOS 批处理文件
REM VIEWDATA REM INSPIRED BY AN EXAMPLE IN "DOS POWERTOOLS" REM BY PAUL SOMERSON @ECHO OFF IF !%1==! GOTO VIEWDATA REM IF NO COMMAND-LINE ARG... FIND "%1" C:\BOZO\BOOKLIST.TXT GOTO EXIT0 REM PRINT LINE WITH STRING MATCH, THEN EXIT. :VIEWDATA TYPE C:\BOZO\BOOKLIST.TXT | MORE REM SHOW ENTIRE FILE, 1 PAGE AT A TIME. :EXIT0 |
脚本转换在某种程度上有所改进。[1]
示例 N-2. viewdata.sh:VIEWDATA.BAT 的 Shell 脚本转换
#!/bin/bash # viewdata.sh # Conversion of VIEWDATA.BAT to shell script. DATAFILE=/home/bozo/datafiles/book-collection.data ARGNO=1 # @ECHO OFF Command unnecessary here. if [ $# -lt "$ARGNO" ] # IF !%1==! GOTO VIEWDATA then less $DATAFILE # TYPE C:\MYDIR\BOOKLIST.TXT | MORE else grep "$1" $DATAFILE # FIND "%1" C:\MYDIR\BOOKLIST.TXT fi exit 0 # :EXIT0 # GOTOs, labels, smoke-and-mirrors, and flimflam unnecessary. # The converted script is short, sweet, and clean, #+ which is more than can be said for the original. |
Ted Davis 的 PC 上的 Shell 脚本 站点有一套关于老式批处理文件编程艺术的综合教程。不幸的是,该页面已消失得无影无踪。
[1] | 各种读者建议对上述批处理文件进行修改,使其更美观、更紧凑和更高效。ABS 指南 的作者认为,这是徒劳的。Bash 脚本可以访问 DOS 文件系统,甚至 NTFS 分区(借助 ntfs-3g)来执行批处理或脚本操作。 |