A Cooly Weblog

   ::  ::  ::  ::  :: 管理

【原创】脚本开发笔记(bash,bat,wsh)

Posted on 2006-07-17 18:47 acooly 阅读(1674) 评论(0)  编辑  收藏 所属分类: Linux/Unix


重庆结行移动商务有限公司

工程技术部门 Java

产品版本

密级

 

V 1.0.0

内部

产品名称:脚本开发笔记

7

 

 

 

 

 

 

脚本开发笔记

 

 

 

 

 

 

 

 

 

重庆结行移动商务有限公司

版权所有   不得复制

 

 


修改历史

 

姓名

版本

完成时间

备注

张浦

1.0.0

2006-4-30

初次建立该文档

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1. 脚本基础 ... 4

1.1.Linux/Unix bash 基础 ... 4

1.1.1.Shell Scripts 简介 ... 4

1.1.2.Bash 语法简介 ... 5

1.1.2.1. 变量 ... 5

1.1.2.1.1. 用户自定义变量 ... 5

1.1.2.1.2. 位置变量 ... 5

1.1.2.1.3. 预定义变量 ... 6

1.1.2.1.4. 环境变量 ... 7

1.1.2.2. 流程控制 ... 7

1.1.2.2.1. if条件控制... 7

1.1.2.2.2. for循环控制... 9

1.1.2.2.3. while/util循环控制... 9

1.1.2.2.4. select10

1.1.2.2.5. case. 10

1.1.2.3. 返回状态 Exit 12

1.1.2.4. 脚本函数 ... 13

1.1.3.Bash 学习资料 ... 14

1.2.Bat 基础 ... 14

1.2.1.Bat 简介 ... 14

1.2.2. 命令和语法简介 ... 14

1.2.2.1.Echo 命令 ... 14

1.2.2.2.@ 命令 ... 15

1.2.2.3.Goto 命令 ... 15

1.2.2.4.rem 命令 ... 15

1.2.2.5.Pause 命令 ... 16

1.2.2.6.Call 命令 ... 16

1.2.2.7.start ... 16

1.2.2.8. choice 命令 ... 17

1.2.2.9. if 命令 ... 18

1.2.2.10.for 命令 ... 19

1.2.2. 参考资料 ... 21

1.3.WSH 基础 ... 21

1.3.1.WSH 简介 ... 21

1.3.2. 简单示例 ... 23

1.3.3. 参考 ... 24

2. 开发实例 ... 24

2.1.BAT 操作 FTP 数据库 ... 24

2.2. 使用 WSF 做复杂程序脚本 ... 25

2.3. 动态更新域名(www.3322.org... 27

2.4. shell 检查 JSP 文件 ... 29

2.5. 自动检测WEB服务器状态并启动(Linux... 31

2.6. 分页 BCP 接口 ... 32

 


1. 脚本基础

 

1.1.Linux/Unix bash 基础

1.1.1 .Shell Scripts 简介

众所皆知地, UNIX 上以小工具著名,利用许多简单的小工具,来完成原本需要大量软体开发的工作,这一点特色,使得 UNIX 成为许多人心目中理想的系统平台。 

  在众多的小工具中, Shell Script 算得上是最基本、最强大、运用最广泛的一个。它运用围之广,不但从系统启动、程式编译、定期作业、上网连线,甚至安装整个 Linux 系统,都可以用它来完成。 

 

  因为 Shell Script 是利用您平日在使用的一些指令,将之组合起来,成为一个 " 程式 " 。如果您平日某些序列的指令下得特别频繁,便可以将这些指令组合起来,成为另一个新的指令。这样,不但可以简化并加速操作速度,甚至还可以干脆自动定期执行,大大简化系统管理工作。 

 

Bash(GNU Bourne-Again SHell) 是许多 Linux 平台的内定 Shell ,事实上,还有许多传统 UNIX 上用的 Shell ,像 tcsh csh ash bsh ksh 等等, Shell Script 大致都类同,当您学会一种 Shell 以后,其它的 Shell 会很快就上手,大多数的时候,一个 Shell Script 通常可以在很多种 Shell 上使用。 

Bourne Again shell (bash), 正如它的名字所暗示的,是 Bourne shell 的扩展。 BASH Bourne shell 完全向后兼容,并且在 Bourne shell 的基础上增加和增强了很多特性。 BASH 也包含了很多 csh Korn Shell 里的优点,使得 BASH 有很灵活和强大的编程接口,同时又有很友好的用户界面。为什么要用 BASH 来代替 sh 呢? Bourne Shell 最大的缺点在于它处理用户的输入方面,在 Bourne shell 里键入命令会很麻烦,尤其当你键入很多相似的命令时,而 BASH 准备了几种特性使命令的输入变得更容易。 BASH 的新功能包括 命令补齐、通配符、命令历史记录、别名等。

1.1.2 .Bash 语法简介

1.1.2 .1. 变量

Bourne Shell 有如下四种变量:

l        用户自定义变量

l        位置变量即 shell script 之参数

l        预定义变量(特殊变量)

l        环境变量

1.1.2 .1.1. 用户自定义变量

a="hello world"

echo $a         

num=2

echo "this is the ${num}nd"

这将打印: this is the 2nd

使用 unset 命令删除变量的赋值

$Z=hello

$echo $Z

hello

$unset Z

 

1.1.2 .1.2. 位置变量

位置变量一般指传入 shell 脚本或函数的参数。

 

 

 

 

$ #

传递到脚本的参数个数

$ *

以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过 9

$ $

脚本运行的当前进程 I D

$ !

后台运行的最后一个进程的进程 I D

 

$ @

$ # 相同,但是使用时加引号,并在引号中返回每个参数

 

$ -

显示 s h e l l 使用的当前选项,与 s e t 命令功能相同

 

$ ?

显示最后命令的退出状态。 0 表示没有错误,其他任何值表明有错误

 

1.1.2 .1.3. 预定义变量

$ shell 变量名的开始,如 $var

 | 管道,将标准输出转到下一个命令的标准输入

 # 注释开始

 & 在后台执行一个进程

  匹配一个字符

 *  匹配 0 到多个字符 ( DOS 不同,可在文件名中间使用,并且含 .)

 $- 使用 set 及执行时传递给 shell 的标志位

 $! 最后一个子进程的进程号

 $# 传递给 shell script 的参数个数

 $* 传递给 shell script 的参数

 $@ 所有参数,个别的用双引号括起来

 $? 上一个命令的返回代码

  当前 shell 的名字

 $n (n:1-) 位置参数

 $$ 进程标识号 (Process Identifier Number, PID)

 >   file 输出重定向

 `command` 命令替换,如 filename=`basename /usr/local/bin/tcsh`

 >>file 输出重定向, append

1.1.2 .1.4. 环境变量

1.1.2 .2. 流程控制

1.1.2 .2.1. if 条件控制

语法:

if ....; then

....

elif ....; then

....

else

....

fi

通常形式:

if [ test ]; then

fi

 

shell 中的 test 表达式:

(1) 字符串操作符   用于计算字符串表达式

test 命令      |    含义

-----------------------------------------

Str1 = str2 | str1 str2 相同时 , 返回 True

Str1 != str2| str1 str2 不同时 , 返回 True

 Str      | str 不是空字符时 , 返回 True

-n str    | str 的长度大于 0 , 返回 True

-z str    | str 的长度是 0 , 返回 True

-----------------------------------------

(2) 整数操作符具有和字符操作符类似的功能 . 只是他们的操作是针对整数

test 表达式   |    含义

---------------------------------------------

Int1 -eq int2| int1 等于 int2 , 返回 True

Int1 -ge int2| int1 大于 / 等于 int2 , 返回 True

Int1 -le int2| int1 小于 / 等于 int2 , 返回 True

Int1 -gt int2| int1 大于 int2 , 返回 True

Int1 -ne int2| int1 不等于 int2 , 返回 True

-----------------------------------------

(3) 用于文件操作的操作符 , 他们能检查 : 文件是否存在 , 文件类型等

test 表达式     |    含义

------------------------------------------------

-d file      | file 是一个目录时 , 返回 True

-f file      | file 是一个普通文件时 , 返回 True

-r file      | file 是一个刻读文件时 , 返回 True

-s file      | file 文件长度大于 0 , 返回 True

-w file      | file 是一个可写文件时 , 返回 True

-x file      | file 是一个可执行文件时 , 返回 True

------------------------------------------------

(4)shell 的逻辑操作符用于修饰 / 连接包含整数 , 字符串 , 文件操作符的表达式

test 表达式      |    含义

----------------------------------------------------------

! expr        | expr 的值是 False , 返回 True

Expr1 -a expr2| expr1,expr2 值同为 True , 返回 True

Expr1 -o expr2| expr1,expr2 的值至少有一个为 True , 返回 True

-----------------------------------------------------------

1.1.2.2. 2 . for 循环 控制

#!/usr/bin/env bash

for myfile in /etc/r*

do

   if [ -d "$myfile" ]

   then

     echo "$myfile (dir)"

   else

     echo "$myfile"

   fi

done

 

1.1.2.2. 3 . while/util 循环 控制

1 :无限回圈写法

#!/bin/sh

while : ; do

echo "do something forever here"

sleep 5

done

 

#!/bin/sh

w hile (true)

do

netstat –ax|grep CONNECTED -wc

sleep 2

done

 

2 :循环记数

#!/bin/sh

i=1

w hile [ $i -le 5 ]

do

echo "do something forever here"

i=`expr $i + 1`

sleep 2

done

1.1.2.2. 4 . select

 

1.1.2.2. 5 . case

case word in [ pattern [ | pattern ] ... ) list ;; ] ... esac

case/esac 的标准用法大致如下 :  

case $arg in  

   pattern | sample) # arg in pattern or sample  

   ;;  

   pattern1) # arg in pattern1  

   ;;  

   *) #default  

   ;;  

esac  

   arg 是您所引入的参数,如果 arg 内容符合 pattern 项目的话,那么便会执行 pattern 以下的程式码,而该段程式码则以两个 --More--(28%) 分号 ";;" 做结尾。 

 

  可以注意到 "case" "esac" 是对称的,如果记不起来的话,把 "case" 颠倒过来即可。 

 

 

*************************

例一 : paranoia.sh

#!/bin/sh  

case in  

     start | begin)  

      echo "start something"  

     ;;  

     stop | end)  

      echo "stop something"  

     ;;  

     *)  

      echo "Ignorant"  

     ;;  

esac  

 

执行

   [root@localhost ~]# chmod 755 paranoia.sh  

   [root@localhost ~]# ./paranoia.sh  

   Ignorant  

   [root@localhost ~]# ./paranoia.sh start  

   start something  

   [root@localhost ~]# ./paranoia.sh begin  

   start something  

   [root@localhost ~]# ./paranoia.sh stop  

   stop something  

   [root@localhost ~]# ./paranoia.sh end  

   stop something  

 

*************************

 

例二 : inetpanel

许多的 daemon 都会附上一个管理用的 Shell Script ,像 BIND 就附上 ndc Apache 就附上 apachectl 。这些管理程式都是用 shell script 来写的,以下示一个管理 inetd shell script 。 

 

#!/bin/sh  

case in  

   start | begin | commence)  

    /usr/sbin/inetd  

   ;;  

   stop | end | destroy)  

    killall inetd  

   ;;  

   restart | again)  

    killall -HUP inetd  

   ;;  

   *)  

    echo "usage: inetpanel [start | begin | commence | stop | end | destory | restart | again]"  

   ;;  

esac  

 

*************************

 

例三 : 判断系统

  有时候,您所写的 Script 可能会跨越好几种平台,如 Linux FreeBSD Solaris 等等,而各平台之间,多多少少都有不同之处,有时候需要判断目前正在那一种平台上执行。此时,我们可以利用 uname 来找出系统资讯。 

#!/bin/sh  

SYSTEM=`uname -s`  

case $SYSTEM in  

   Linux)  

     echo "My system is Linux"  

     echo "Do Linux stuff here..."  

   ;;  

   FreeBSD)  

     echo "My system is FreeBSD"  

     echo "Do FreeBSD stuff here..."  

   ;;  

   *)  

echo "Unknown system : $SYSTEM"  

     echo "I don't what to do..."  

   ;;  

esac  

 

1.1.2.3. 返回状态 Exit

返回状态值 - Exit Status 。因为 if/while/until 都迁涉到了使用 Exit Status 来控制程式流程的问题。许多人都知道,在许多语言中 (C/C++/Perl....) ,都有一个 exit 的函数,甚至连 Bash 自己都有个 exit 的内建命令。而 exit 后面所带的数字,便是返回状态值 - Exit Status 。返回状态值可以使得程式与程式之间,利用 Shell script 来结合的可能性大增,利用小程式,透过 Shell script ,来完成很杂的工作。 

shell 中,返回值为零表示成功 (True) ,非零值为失败 (False) 。 

 

举例来说,以下这个两个小程式 yes/no 分别会返回 0/1( 成功 / 失败 ):  

/* yes.c */  

void main(void) { exit(0); }  

/* no.c */  

void main(void) { exit(1); }  

那么以下这个 "YES" shell script 便会显示 "YES" 。 

#!/bin/sh  

# YES  

if yes ; then  

echo "YES"  

fi  

"NO" 不会显示任何东西。 

#!/bin/sh  

# NO  

if no ; then  

echo "YES"  

fi  

 

 

1.1.2.4. 脚本函数

[ function ] name () { list; }

function 的参数是 Positional Paraments 。 

 

 

1.1.3.Bash 学习资料

IBM developerWorks

http://www.ibm.com/Search/?q=bash&v=14&lang=zh&cc=cn&en=utf

 

1.2.Bat 基础

1.2.1.Bat 简介

批处理文件是无格式的文本文件,它包含一条或多条命令。它的文件扩展名为 .bat .cmd 。在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用 Cmd.exe 按照该文件中各个命令出现的顺序来逐个运行它们。使用批处理文件(也被称为批处理程序或脚本),可以简化日常或重复性任务。

 

1.2.2. 命令和语法简介

 

1.2.2.1.Echo 命令

打开回显或关闭请求回显功能,或显示消息。如果没有任何参数, echo 命令将显示当前回显设置。

语法

echo [{on|off}] [message]

Sample @echo off / echo hello world

在实际应用中我们会把这条命令和重定向符号(也称为管道符号,一般用 > >> ^ )结合来实现输入一些命令到特定格式的文件中 . 这将在以后的例子中体现出来。

 

1.2.2.2.@ 命令

表示不显示 @ 后面的命令。

Sample @echo off

@echo Now initializing the program,please wait a minite...

 

1.2.2.3.Goto 命令

指定跳转到标签,找到标签后,程序将处理从下一行开始的命令。

语法: goto label label 是参数,指定所要转向的批处理程序中的行。)

Sample

rem 如果这里的 if %1 %2 你不明白的话,先跳过去,后面会有详细的解释。

if {%1}=={} goto noparms

if {%2}=={} goto noparms

@Rem check parameters if null show usage

:noparms

echo Usage: monitor.bat ServerIP PortNumber

goto end

标签的名字可以随便起,但是最好是有意义的字母啦,字母前加个:用来表示这个字母是标签, goto 命令就是根据这个:来寻找下一步跳到到那里。最好有一些说明这样你别人看起来才会理解你的意图啊。

 

1.2.2.4.rem 命令

注释命令,在 C 语言中相当与 /*--------*/, 它并不会被执行,只是起一个注释的作用,便于别人阅读和你自己日后修改。

Rem Message

Sample

@Rem Here is the description

 

1.2.2.5.Pause 命令

运行 Pause 命令时,将显示下面的消息:

Press any key to continue . . .

Sample

@echo off

:begin

copy a:*.* d \back

echo Please put a new disk into driver A

pause

goto begin

在这个例子中,驱动器 A 中磁盘上的所有文件均复制到 d:\back 中。显示的注释提示您将另一张磁盘放入驱动器 A 时, pause 命令会使程序挂起,以便您更换磁盘,然后按任意键继续处理。

 

1.2.2.6.Call 命令

从一个批处理程序调用另一个批处理程序,并且不终止父批处理程序。 call 命令接受用作调用目标的标签。如果在脚本或批处理文件外使用 Call ,它将不会在命令行起作用。

语法

call [[Drive:][Path] FileName [BatchParameters]] [:label [arguments]]

参数

[Drive:}[Path] FileName

指定要调用的批处理程序的位置和名称。 filename 参数必须具有 .bat .cmd 扩展名。

1.2.2.7.start 命令

调用外部程序,所有的 DOS 命令和命令行程序都可以由 start 命令来调用。

常用参数:

MIN 开始时窗口最小化

SEPARATE 在分开的空间内开始 16 Windows 程序

HIGH HIGH 优先级类别开始应用程序

REALTIME REALTIME 优先级类别开始应用程序

WAIT 启动应用程序并等候它结束

parameters 这些为传送到命令 / 程序的参数

执行的应用程序是 32- GUI 应用程序时, CMD.EXE 不等应用程序终止就返回命令提示。如果在命令脚本内执行,该新行为则不会发生。

 

1.2.2.8. choice 命令

choice 使用此命令可以让用户输入一个字符,从而运行不同的命令。使用时应该加 /c: 参数, c: 后应写提示可输入的字符,之间无空格。它的返回码为 1234 ……

: choice /c:dme defrag,mem,end

将显示

defrag,mem,end[D,M,E]?

Sample

Sample.bat 的内容如下 :

@echo off

choice /c:dme defrag,mem,end

if errorlevel 3 goto defrag (应先判断数值最高的错误码)

if errorlevel 2 goto mem

if errotlevel 1 goto end

 

:defrag

c:\dos\defrag

goto end

:mem

mem

goto end

:end

echo good bye

 

此文件运行后,将显示 defrag,mem,end[D,M,E]? 用户可选择 d m e ,然后 if 语句将作出判断, d 表示执行标号为 defrag 的程序段, m 表示执行标号为 mem 的程序段, e 表示执行标号为 end 的程序段,每个程序段最后都以 goto end 将程序跳到 end 标号处,然后程序将显示 good bye ,文件结束。

1.2.2.9. if 命令

if 表示将判断是否符合规定的条件,从而决定执行不同的命令。 有三种格式 :

1 if " 参数 " == " 字符串 "  待执行的命令

参数如果等于指定的字符串,则条件成立,运行命令,否则运行下一句。 ( 注意是两个等号)

if "%1"=="a" format a:

if {%1}=={} goto noparms

if {%2}=={} goto noparms

 

2 if exist 文件名  待执行的命令

如果有指定的文件,则条件成立,运行命令,否则运行下一句。

if exist config.sys edit config.sys

 

3 if errorlevel / if not errorlevel 数字  待执行的命令

如果返回码等于指定的数字,则条件成立,运行命令,否则运行下一句。

if errorlevel 2 goto x2  

DOS 程序运行时都会返回一个数字给 DOS ,称为错误码 errorlevel 或称返回码,常见的返回码为 0 1

 

1.2.2.10.for 命令

for 命令是一个比较复杂的命令,主要用于参数在指定的范围内循环执行命令。

在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable

 

for {%variable|%%variable} in (set) do command [ CommandLineOptions]

%variable 指定一个单一字母可替换的参数。

(set) 指定一个或一组文件。可以使用通配符。

command 指定对每个文件执行的命令。

command-parameters 为特定命令指定参数或命令行开关。

在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable

而不要用 %variable 。变量名称是区分大小写的,所以 %i 不同于 %I

 

如果命令扩展名被启用,下列额外的 FOR 命令格式会受到

支持 :

 

FOR /D %variable IN (set) DO command [command-parameters]

 

如果集中包含通配符,则指定与目录名匹配,而不与文件

名匹配。

 

FOR /R [[drive:]path] %variable IN (set) DO command [command-

 

检查以 [drive:]path 为根的目录树,指向每个目录中的

FOR 语句。如果在 /R 后没有指定目录,则使用当前

目录。如果集仅为一个单点 (.) 字符,则枚举该目录树。

 

FOR /L %variable IN (start,step,end) DO command [command-para

 

该集表示以增量形式从开始到结束的一个数字序列。

因此, (1,1,5) 将产生序列 1 2 3 4 5 (5,-1,1) 将产生

序列 (5 4 3 2 1)

 

FOR /F ["options"] %variable IN (file-set) DO command

FOR /F ["options"] %variable IN ("string" DO command

FOR /F ["options"] %variable IN (command) DO command

 

或者,如果有 usebackq 选项 :

 

FOR /F ["options"] %variable IN (file-set) DO command

FOR /F ["options"] %variable IN ("string" DO command

FOR /F ["options"] %variable IN (command) DO command

 

filenameset 为一个或多个文件名。继续到 filenameset 中的

下一个文件之前,每份文件都已被打开、读取并经过处理。

处理包括读取文件,将其分成一行行的文字,然后将每行

解析成零或更多的符号。然后用已找到的符号字符串变量值

调用 For 循环。以默认方式, /F 通过每个文件的每一行中分开

的第一个空白符号。跳过空白行。您可通过指定可选 "options"

参数替代默认解析 * 作。这个带引号的字符串包括一个或多个

指定不同解析选项的关键字。这些关键字为 :

 

eol=c - 指一个行注释字符的结尾 ( 就一个 )

skip=n - 指在文件开始时忽略的行数。

delims=xxx - 指分隔符集。这个替换了空格和跳格键的

默认分隔符集。

tokens=x,y,m-n - 指每行的哪一个符号被传递到每个迭代

for 本身。这会导致额外变量名称的

格式为一个范围。通过 nth 符号指定 m

符号字符串中的最后一个字符星号,

那么额外的变量将在最后一个符号解析之

分配并接受行的保留文本。

usebackq - 指定新语法已在下类情况中使用 :

在作为命令执行一个后引号的字符串并且

引号字符为文字字符串命令并允许在 fi

中使用双引号扩起文件名称。

 

1.2.2. 参考资料

Windows 帮助

MSDN

1.3.WSH 基础

1.3.1.WSH 简介

WSH 是“ Windows Scripting Host ”的缩略形式,其通用的中文译名为“ Windows 脚本宿主”。对于这个较为抽象的名词,我们可以先作这样一个笼统的理解:它是内嵌于 Windows 操作系统中的脚本语言工作环境。

Windows Scripting Host 这个概念最早出现于 Windows 98 操作系统。大家一定还记得 MS-Dos 下的批处理命令,它曾有效地简化了我们的工作、带给我们方便,这一点就有点类似于如今大行其道的脚本语言。但就算我们把批处理命令看成是一种脚本语言,那它也是 98 版之前的 Windows 操作系统所唯一支持的“脚本语言”。而此后随着各种真正的脚本语言不断出现,批处理命令显然就很是力不从心了。面临这一危机,微软在研发 Windows 98 时,为了实现多类脚本文件在 Windows 界面或 Dos 命令提示符下的直接运行,就在系统内植入了一个基于 32 Windows 平台、并独立于语言的脚本运行环境,并将其命名为“ Windows Scripting Host ”。 WSH 架构于 ActiveX 之上,通过充当 ActiveX 的脚本引擎控制器, WSH Windows 用户充分利用威力强大的脚本指令语言扫清了障碍。

 

再具体一点描述:你自己编写了一个脚本文件,如后缀为 .vbs .js 的文件,然后在 Windows 下双击并执行它,这时,系统就会自动调用一个适当的程序来对它进行解释并执行,而这个程序,就是 Windows Scripting Host ,程序执行文件名为 Wscript.exe (若是在命令行下,则为 Cscript.exe )。

 

WSH 诞生后,在 Windows 系列产品中很快得到了推广。除 Windows 98 外,微软在 Internet Information Server 4.0 Windows Me Windows 2000 Server ,以及 Windows 2000 Professional 等产品中都嵌入了 WSH 。现在,早期的 Windows 95 也可单独安装相应版本的 WSH 。(附:各种版本 WSH 的安装程序可以从 http://msdn.microsoft.com/scripting 站点下载)。

 

WSH 的设计,在很大程度上考虑到了“非交互性脚本( noninteractive scripting )”的需要。在这一指导思想下产生的 WSH ,给脚本带来非常强大的功能,例如:我们可以利用它完成映射网络驱动器、检索及修改环境变量、处理注册表项等工作;管理员还可以使用 WSH 的支持功能来创建简单的登陆脚本,甚至可以编写脚本来管理活动目录。

 

而事实上,上述功能的实现,均与 WSH 内置的多个对象密切相关,这些内置对象肩负着直接处理脚本指令的重任。因此,我们也可以通过了解 WSH 的内置对象来探寻 WSH 可以实现的功能。

 

WSH 自带的几个内置对象包括:

 

1. Wscript.exe 提供的对象

Wscript 作为 Wscript 公开给脚本引擎。

WshArguments 未公开;通过 Wscript.Arguments 属性访问。

 

2. WSHom.Ocx 提供的对象。

WshShell 自动对象。

ProgID Wscript.WshShell

WshNetwork 自动对象。 ProgID Wscript.WshNetwork

WshShortcut 未公开;通过 WshShell.CreateShortcut 方法访问。

WshUrlShortcut 未公开;通过 WshShell.CreateShortcut 方法访问。

WshCollection 未公开;通过 WshNetwork.EnumNetworkDrives WshNetwork.EnumPrinterConnection 方法访问。

WshEnvironment 未公开;通过 WshShell.Environment 属性访问。

WshSpecialFolders 未公开;通过 WshShell.Folder 属性访问。

 

他们主要可以完成环境变量的获取,网络登陆,驱动器映射,快截方式创建,程序加载,特殊文件夹(如系统文件夹)信息获取等功能。

如果你的系统里支持 ADO COM 部件,你同样可以使用。

1.3.2. 简单示例

下面这个例子演示打开写字板查看文本文件,同时创建一个文本文件并写入一段话,你可以把他拷贝到写字板中,然后以 .vbs 为后缀存盘,之后双击他,

 

test.vbs

Set WshShell = Wscript.CreateObject("Wscript.Shell")

WshShell.Run ("notepad " & Wscript.ScriptFullName)

' 上面用 SHELL 对象启动程序

 

Set fs = Wscript.CreateObject("Scripting.FileSystemObject")

Set a = fs.CreateTextFile("c:\testfile.txt", True)

a.WriteLine(" 这是一个测试。 ")

a.Close

 

1.3.3. 参考

ü        http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/8bcd5aee-e5bf-426f-8f41-5cb11efef102.asp

ü         http://www.yesky.com/20010711/188622_1.shtml

ü         IIS PWS文档

 

2. 开发实例

2.1.BAT 操作 FTP 和数据库

脚本类型: windows bat

c 为:

l        通过系统时间构建目标文件名。

l        从目标 FTP 服务器下载确定文件名的数据文件到本地

l        删除数据库中对应数据表记录

l        把数据文件导入数据库中

l        备份数据文件

 

主程序: gift.bat

echo off

mkdir data

echo 通过 ftp 取得文件

ctime "giftlist_%%Y%%m%%d" > time

copy /b ftp1.txt + time + ftp2.txt ftp.txt

ftp -n 192.168.0.86 < ftp.txt > ftp.log

echo 把文件 bcp 到数据库表 CMSS..GIFT_LIST

isql -Ucmssuser -Sinfo1 -Pinfocmss_ > sql.log < sql.sql

copy /b bcp1.txt + time + bcp2.txt bcptable.bat

call bcptable.bat

copy /b move1.txt + time + move2.txt move.bat

call move.bat

del move.bat

del time

del ftp.txt

 

2.2. 使用 WSF 做复杂程序脚本

脚本类型: Windows Scripting Host

程序功能:

l        获取参数并通过正则检测参数合法性

l        读取模板文件,并通过正则生成目标文件

l        调用数据库执行生成的 SQL 脚本

l        Bcp 取得数据表数据

l        压缩生成的数据文件

l        FTP 数据文件到接口服务器

 

主程序文件: telfeelist.wsf

<job id="telfeelist">

  <script language="JScript">  

    var now = new Date();

    var temptable = now.getYear()+""+(now.getMonth()+1)+""+now.getDate();

    var Path = WScript.ScriptFullName;

    Path = Path.substring(0,Path.lastIndexOf("\\")+1);

    var title = " 代理商号码返费明细 ";

    var WshShell = WScript.CreateObject("WScript.Shell");

    if(WScript.Arguments.count() != 2){

      WshShell.Popup(" 请输入参数: \nUsage:TELFEELIST PERIOD(yyyyMM),AGENTID",0,title,0);

      WScript.Quit(0);

    }

    // 当前帐期

    var period = WScript.Arguments.Item(0);

    // 代理商编码

    var agentid = WScript.Arguments.Item(1);

    var re = /^[0-9]{6}$/i;

    if(!re.test(period)){

      WScript.Echo("Usage:PERIOD 格式为 :yyyyMM");

      WScript.Quit(0);   

    }

   

    // 月表后缀

    var postfix = period.substring(4,6);

    var p_period = period - 1;

    if(postfix == "01"){

      p_period = (parseInt(period.substring(0,4)) - 1) + "12";

    }

   

    var objFSO = WScript.CreateObject("Scripting.FileSystemObject");

    var objReadFile = objFSO.OpenTextFile("TELFEELIST.SQL", 1);

    var SQL = objReadFile.ReadAll();

    objReadFile.Close();

    // 替换 $PERIOD$ period

    re = new RegExp("_PERIOD_","g");

    var SQL = SQL.replace(re,period);

    re = new RegExp("_AGENTID_","g");

              var SQL = SQL.replace(re,agentid);

              re = new RegExp("_POSTFIX_","g");

              var SQL = SQL.replace(re,postfix);

              re = new RegExp("_PPERIOD_","g");

              var SQL = SQL.replace(re,p_period);

              re = new RegExp("_TEMPTABLE_","g");

              var SQL = SQL.replace(re,temptable);

                           

              var tempSQLFile = "TELFEELIST_" + period + ".sql";

             

              // SQL 文件

              var objTStream = objFSO.CreateTextFile(tempSQLFile, true, false);

              objTStream.WriteLine(SQL);

    objTStream.Close();

 

              var batfile = Path + "TELFEELIST.bat";

             

              var objTStream = objFSO.CreateTextFile(batfile, true, false);

    // 执行 SQL 文件

    var cmd = "isql -Sinfo2 -Ucmssuser -Pinfocmss_ < "+Path+tempSQLFile;

              objTStream.WriteLine(cmd);

     

      // 把结果数据 bcp 出文件

      temptable = "MENSAL_TELSTATE_" + temptable

      var bcpfile = Path + "TELFEELIST_"+period+".txt";

      cmd = "bcp AGENT.." + temptable + " out " + bcpfile + " -c -Sinfo2 -Pinfocmss_ -Ucmssuser";

      objTStream.WriteLine(cmd);

     

      // 删除临时表 temptable

     

      cmd = "echo "+temptable+" > temptable"

      objTStream.WriteLine(cmd);

      cmd = "copy /b drop1.sql+temptable+drop2.sql drop.sql"

      objTStream.WriteLine(cmd);

      cmd = "isql -Sinfo2 -Ucmssuser -Pinfocmss_ < "+Path+"drop.sql"

      objTStream.WriteLine(cmd);

     

      // 压缩文件

      var rarfile = Path+"TELFEELIST_"+period+".rar";

      cmd = "rar a "+rarfile+" "+"TELFEELIST_"+period+".txt";

      objTStream.WriteLine(cmd);

     

     

      //FTP 转送文件

        cmd = "echo " + rarfile + " > ftpfile"

      objTStream.WriteLine(cmd);

      cmd = "copy /b ftp1.txt+ftpfile+ftp2.txt ftp.txt"

      objTStream.WriteLine(cmd);

      cmd = "ftp -n 218.201.39.11 < ftp.txt > ftp.log"

      objTStream.WriteLine(cmd);

      //cmd = "del /Q ftp.txt\ndel /Q "+

      objTStream.Close();

     

      // 执行 bat 文件

      //WshShell.run("cmd /c "+batfile,0,true);

      //WshShell.Popup(" 执行成功! ",0,title,32);

      WScript.Quit(0);

  </script>

</job>

 

 

2.3. 动态更新域名( www.3322.org

脚本类型: bash

功能说明:

动态域名可以使您拥有一个固定的域名,对应一个可变的 IP 地址。这样 Internet 用户就可以使用这个固定的域名,方便地来访问您的计算机。比如,您是个宽带上网用户,您的 ISP (如网通)提供给您的是一个可变的 IP 。但是,您到希网网络申请一个动态域名,如 zpu.3322.org ,然后下载一个客户端软件,您的用户就可以使用 zpu.3322.org 来访问您的计算机。详细信息请参照: http://www.3322.org

希网提供了 windows linux/unix 的客户端, windows 客户端很好用,启动的时候自动加载,并定时更新动态域名,但是希网提供的 linux 客户端指提供 linux 下直接拨号上网方式的更新,对于使用了路由器,在 linux 系统中无法用 ifconfig 查到外网 IP 的情况就无法解决了。

我们可以采用脚本的方式,自己来更新动态域名。主要原理如下:

l        访问本地的路由器管理页面,分析 HTML 页面并得到路由器的真实 IP

l        更具动态域名更新协议(希网提供),使用 wget 更新动态域名

l        加入本脚本到系统 crontab 中定时更新域名

 

主程序: updateip.sh

#!/bin/sh

# ip update from  Router WEB Manager

# curdate=date +"%Y-%m-%d %H:%M:%S"

 

LOG_FILE=/g/linux_tools/bin/dydns.log

 

echo `date +"%Y-%m-%d %H:%M:%S"` >> $LOG_FILE

wget -q -C off -O remoteip http://admin:admin@192.168.1.1/userRpm/StatusRpm.htm

iptmp=`sed -n '/IP/p' remoteip |sed '1d'|sed 's/<[a-z,\/]*>//g'|sed 's/^IP.\{4\}//g'`

if [ -z "$iptmp" ]; then

  echo "no connecting internet." >> $LOG_FILE

else

  rm -f ipupdate

  wget -q -C off -O ipupdate "http://cqpower:cqpower.net@members.3322.org/dyndns/update?&hostname=zpu.3322.org&myip=$iptmp"

  ret=`awk '{if($1~/good/ || $1~/nochg/) print $1}' ipupdate|sed -n '1p'`

  if [ "$ret"="good" -o "$ret"="nochg" ]; then

    echo "update internet ip success:$iptmp" >> $LOG_FILE

  else

    echo "update internet ip failure!"  >> $LOG_FILE

  fi

fi

 

2.4. shell 检查 JSP 文件

shell 脚本: checkfile.sh 检查 JSP 文件中数据库连接是否关闭 (CQMC)

 

#!/bin/sh

# check database connection state of jsp file

 

# check_conn

# to call: check_conn file

check_conn(){

  if [ $# != 1 ]; then

    echo "Usage:check_conn file"

    return 1

  fi

  _file=$1

  if [ -f "$_file" -a -r "$_file" ]

  then

     _sedopen=`sed -n '/conn.jsp/p' $_file`

     _sedclose=`sed -n '/conn.close/p' $_file`

     if [ "$_sedopen" != "" -a "$_sedclose" = "" ]

     then

       echo $_file

       return 0

     fi

  else

    echo "$_file can not be open"

    return 1

  fi

}

 

 

# recursion file list

# tocall: ftree path logfile

ftree(){

  if [ $# != 2 ]; then

    echo "Usage:ftree path logfile"

    return 1

  fi 

  _dir=$1

  _log=$2

  if [ ! -d "$_dir" -o ! -r "$_dir" ]

  then

    echo "$_dir can not be operation."

    return 1

  fi

  for file in `ls -1 $_dir`

  do

    if [ -d "$_dir/$file" ]; then

      (ftree $_dir/$file $_log)

    else

      echo $_dir/$file >> filelist

      #() 表示在子 shell 中执行不影响当前 shell 的执行,相当于多线程应用

(

      if [ `echo $file|awk '{if($1~/^.*.jsp/) print 0}'` ]; then

        _check="`check_conn $_dir/$file`"

        if [ "$_check" != "" ]; then

          echo $_check >> $_log

        fi

      fi

      )

    fi

  done

  return 0

}

:

# func progress bar

# to call: procbar curval,maxval

procbar(){

  curval=$1

  maxval=$2

  barno=`expr 100 \* $curval / $maxval`

  count=0

  while [ $count -lt $barno ]

  do

    echo -n "|"

    count=`expr $count + 1`

    sleep 1

  done 

}

 

 

# BEGIN

# procbar 5 30

FILEPATH=$1

LOGFILE=$2

if [ $# != 2 ]; then

  echo "Usage:checkfile FILEPATH LOGFILE"

else

  ftree $FILEPATH $LOGFILE

fi

# END

 

 

2.5. 自动检测 WEB 服务器状态并启动( Linux

 

restart.sh

#!/bin/sh

# check the web server ,if no running,startup it.

# author:ZhangPu [2005-11-23 17:22:50]

# RetHat Linux 9.0 + tomcat 4.13

 

#setting enviroment

export JAVA_HOME=/usr/java/j2sdk1.4.1_05

export CATALINA_HOME=/usr/tomcat-4.1.24

export CATALINA_OPTS="-Xms800m -Xmx800m"

export LANG=zh_CN.GB18030

URL=http://localhost

SFILE=/usr/tomcat-4.1.24/bin/index

LOGFILE=/usr/tomcat-4.1.24/bin/restart.log

 

# checking web server

if ! wget -q -s -C off -O $SFILE $URL

then

 STATE=`sed -n "1p" $SFILE`

 if [ "$STATE" != "HTTP/1.1 200" ]; then

   echo "[`date +'%Y-%m-%d %H:%M:%S'`]" >> $LOGFILE

   echo "Shutdowning" >> $LOGFILE

   ($CATALINA_HOME/bin/shutdown.sh)

   sleep 2

   killall java

   sleep 3

   killall java

   echo "Shutdown successful." >> $LOGFILE

   echo "Startuping..." >> $LOGFILE

   ($CATALINA_HOME/bin/startup.sh)

   sleep 3

   reply=`ps -ax|grep java|grep Xms`

   if [ "$reply" != "" ]; then

     echo "Startup successful." >> $LOGFILE

   fi

 fi

fi

rm -f $SFILE

 

2.6. 分页 BCP 接口

脚本类型: bash

程序功能

按预定的接口规范,从数据库中按指定的记录数生成多个数据文件,并通过 FTP 方式发送到接口机器上。( BCP 分页)

主程序: main.sh

#!/bin/sh

# todo: main.sh

 

if [ "$#" != "1" ]

then

  echo Usage:main.sh tablename

  exit

fi

 

# env

SYBASE=/app/sybase/

SYBASE_ASE=ASE-12_5

SYBASE_OCS=OCS-12_5

 

APP_HOME=/app/sybase/cmss2boss

DATA_TEMP=/app/sybase/cmss2boss/temp

#. $SYBASE/SYBASE.sh

TBCOUNT=`$APP_HOME/getdbcount.sh IC_STOCK_DETAIL`

PAGECOUNT=1

PAGESIZE=100000

 

TABLENAME=$1

OVERFLAG_FILENAME=COMPLETE

 

if [ "`expr $TBCOUNT % $PAGESIZE`" != "0" ]

then

  PAGECOUNT=`expr $TBCOUNT / $PAGESIZE`

  PAGECOUNT=`expr $PAGECOUNT + 1`

else

  PAGECOUNT=`expr $TBCOUNT / PAGESIZE`

fi

 

echo $PAGECOUNT

 

i=1

while [ $i -le $PAGECOUNT ]; do

  echo bcp page $i

  FILENAME=`$APP_HOME/genfilename.sh $TABLENAME ROOT $i 0`

  START=`expr $i - 1`

  START=`expr $START \* $PAGESIZE`

  START=`expr $START + 1`

  END=`expr $i \* $PAGESIZE`

  echo star:$START

  echo end:$END

  bcp CMSS..$TABLENAME out $DATA_TEMP/$FILENAME -c -t"" -r"\r\n" -F$START -L$END -SINFO1 -Ucmssuser -Pinfocmss_

  VALIDATE_FILENAME=`$APP_HOME/genfilename.sh $TABLENAME ROOT $i 1`

  touch $DATA_TEMP/${VALIDATE_FILENAME}

  i=`expr $i + 1`

done

#complete flag file

touch $DATA_TEMP/${OVERFLAG_FILENAME}

 

$APP_PATH/ftp.sh

 

rm -f $DATA_TEMP/*

 

 


只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问