将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脚本有异曲同工之妙.