Appendix L. 将DOS批处理文件转换为Shell脚本
相当多的在PC上学习脚本的程序员都在运行DOS. 事实上, 残废的DOS批处理文件语言还是可以编写出一些比较强大的脚本来的, 虽然它们一般都需要借助于外部的工具. 所以说, 某些时候, 我们还是需要将老式的DOS批处理文件转换为UNIX shell脚本. 一般来说, 做这种事情并不困难, 因为DOS批处理文件操作不过是等价的shell脚本的一个受限子集.
表格 L-1. 批处理文件关键字 / 变量 / 操作符, 和等价的shell符号
批处理文件操作符 |
Shell脚本等价符号 |
含义 |
% |
$ |
命令行参数前缀 |
/ |
- |
命令选项标记 |
\ |
/ |
目录路径分隔符 |
== |
= |
(等于)字符串比较测试 |
!==! |
!= |
(不等)字符串比较测试 |
| |
| |
管道 |
@ |
set +v |
不打印当前命令 |
* |
* |
文件名"通配符" |
> |
> |
文件重定向(覆盖) |
>> |
>> |
文件重定向(附加) |
< |
< |
重定向stdin |
%VAR% |
$VAR |
环境变量 |
REM |
# |
注释 |
NOT |
! |
取反 |
NUL |
/dev/null |
"黑洞"用来阻止命令输出 |
ECHO |
echo |
打印(Bash中有更多选项) |
ECHO. |
echo |
打印空行 |
ECHO OFF |
set +v |
不打印后续的命令 |
FOR %%VAR IN (LIST) DO |
for var in [list]; do |
"for"循环 |
:LABEL |
没有等价物(多余) |
标签 |
GOTO |
没有等价物(使用函数) |
跳转到脚本的另一个位置 |
PAUSE |
sleep |
暂停或等待一段时间 |
CHOICE |
case or select |
菜单选择 |
IF |
if |
if条件语句 |
IF EXIST FILENAME |
if [ -e filename ] |
测试文件是否存在 |
IF !%N==! |
if [ -z "$N" ] |
参数"N"是否存在 |
CALL |
source命令或.(点操作符) |
"include"另一个脚本 |
COMMAND /C |
source命令或.(点操作符) |
"include"另一个脚本(与CALL相同) |
SET |
export |
设置一个环境变量 |
SHIFT |
shift |
左移命令行参数列表 |
SGN |
-lt或-gt |
(整形)符号 |
ERRORLEVEL |
$? |
退出状态 |
CON |
stdin |
"控制台"(stdin) |
PRN |
/dev/lp0 |
(一般的)打印设备 |
LPT1 |
/dev/lp0 |
第一个打印设备 |
COM1 |
/dev/ttyS0 |
第一个串口 |
批处理文件一般都包含DOS命令. 我们必须把它转换为UNIX的等价命令, 这样我们才能把批处理文件转换为shell脚本文件.
表格 L-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 |
mv |
重命名(移动) |
RD |
rmdir |
删除目录 |
RMDIR |
rmdir |
删除目录 |
SORT |
sort |
排序文件 |
TIME |
date |
显示系统时间 |
TYPE |
cat |
将文件输出到stdout |
XCOPY |
cp |
(扩展的)文件拷贝 |
 |
事实上, 几乎所有的UNIX和shell操作符, 还有命令都有许多的选项, 对比DOS和批处理文件来说, 它们要强大的多. 许多DOS批处理文件都需要依靠辅助工具, 比如ask.com, 这是一个比read命令差很多的类似副本.
DOS对于文件名通配符扩展支持的非常有限, 并且很不完整, 仅仅识别*和?. |
将DOS批处理文件转换为sehll脚本, 通常是一件很简单的事情, 而且转换的结果通常都比原始的批处理文件好.
例子 L-1. VIEWDATA.BAT: DOS批处理文件
1 REM VIEWDATA
2
3 REM 灵感来自于例子"DOS POWERTOOLS"
4 REM PAUL SOMERSON编写
5
6
7 @ECHO OFF
8
9 IF !%1==! GOTO VIEWDATA
10 REM 如果没有命令行参数...
11 FIND "%1" C:\BOZO\BOOKLIST.TXT
12 GOTO EXIT0
13 REM 打印出字符串匹配的行, 然后退出.
14
15 :VIEWDATA
16 TYPE C:\BOZO\BOOKLIST.TXT | MORE
17 REM 显示整个文件, 一次一页.
18
19 :EXIT0 |
转换脚本作了一些改进.
例子 L-2. viewdata.sh: 转换自VIEWDATA.BAT的shell脚本
1 #!/bin/bash
2 # viewdata.sh
3 # 转换自VIEWDATA.BAT的shell脚本.
4
5 DATAFILE=/home/bozo/datafiles/book-collection.data
6 ARGNO=1
7
8 # @ECHO OFF 这个命令在这里就不需要了.
9
10 if [ $# -lt "$ARGNO" ] # IF !%1==! GOTO VIEWDATA
11 then
12 less $DATAFILE # TYPE C:\MYDIR\BOOKLIST.TXT | MORE
13 else
14 grep "$1" $DATAFILE # FIND "%1" C:\MYDIR\BOOKLIST.TXT
15 fi
16
17 exit 0 # :EXIT0
18
19 # 跳转, 标签, 还有其他一些小手段, 在shell脚本中就不需要了.
20 # 我们可以说, 转换后的脚本比原始批处理文件好的多,
21 #+ 它更短, 看起来更整洁, 更优雅. |
Ted Davis的Shell Scripts on the PC站点上有许多关于老式的批处理文件编程的教程, 他使用的某些独创性的技术, 和shell脚本有异曲同工之妙.
|