Xi's profile风中的甜椒PhotosBlogListsMore Tools Help

Blog


    March 12

    shell 备忘

    13.2.3 Shell 参数

    几个需要记住的特殊参数

         $0      = shell 名称或 shel 脚本名称
         $1      = 第一个(1)shell 参数
          ...
         $9      = 第九个(9)shell 参数
         $#      = 位置参数的个数
         "$*"    = "$1 $2 $3 $4 ... $n"
         "$@"    = "$1" "$2" "$3" "$4" ... "$n"
         $?      = 最近执行的命令的退出状态
         $$      = 当前 shell 脚本的 PID
         $!      = 最近启动的后台作业的 PID
    

    需要记住的基本扩展参数

             形式        如果设置了 var      如果没有设置 var
         ${var:-string}  $var                string
         ${var:+string}  string              null
         ${var:=string}  $var                string 
                                             (并且执行 var=string)
         ${var:?string}  $var                (返回 string 然后退出)
    

    在此,冒号“:”在所有运算表达式中事实上均是可选的。

    • 有“:” = 运算表达式测试“存在”和“非空”。

    • 没有“:” = 运算表达式仅测试“存在”。

    需要记住的替换参数

             形式        	结果
         ${var%suffix}   删除位于 var 结尾的 suffix 最小匹配模式
         ${var%%suffix}  删除位于 var 结尾的 suffix 最大匹配模式
         ${var#prefix}   删除位于 var 开头的 prefix 最小匹配模式
         ${var##prefix}  删除位于 var 开头的 prefix 最大匹配模式
    

    13.2.4 Shell 重定向

    需要记住的基本重定向(redirection)运算符(在此[n]表示定义文件描述符的可选参数):

         [n]> file     重定向标准输出(或 n)到 file。
         [n]>> file    重定向标准输出(或 n)到 file。
         [n]< file     将file重定向到标准输入(或 n)。
         [n1]>&n2      重定向标准输出(或 n1) 到n2。
         2> file >&2    重定向标准输出和错误输出到 file。
         | command     将标准输出通过管道传递给 command。
         2>&1 | command 将标准输出或错误输出通过管道传递给 command。
    

    在这里:

    • stdin: 标准输入 (文件描述符 = 0)

    • stdout: 标准输出 (文件描述符 = 1)

    • stderr: 标准错误 (文件描述符 = 2)

    shell 允许你通过使用 exec 内嵌一个任意的文件描述符来打开文件。

         $ echo Hello >foo
         $ exec 3<foo 4>bar  # 打开文件
         $ cat <&3 >&4       # 重定向标准输入到 3,标准输出到 4
         $ exec 3<&- 4>&-    # 关闭文件
         $ cat bar
         Hello
    

    在这里, n<&- 和 n>&- 表示关闭文件描述符 n。


    13.2.5 Shell 条件表达式

    每条命令均可返回一个退出状态,这个状态值可用于条件表达式:

    • 成功:0 (True)

    • 错误:1–255 (False)

    注意该用法,返回值0用来表示“true”与计算机其它领域中常见的转换是不同的。另外`['等阶于使用test命令进行参数赋值`]'相当于一个条件表达式。

    需要记住的常用基本条件表达式

         command && if_success_run_this_command_too || true
         command || if_not_success_run_this_command_instead
         
         if [ conditional_expression ]; then  
          if_success_run_this_command
         else
          if_not_success_run_this_command
         fi
    

    当 shell 使用 -e 调用的时候, 需要使用 || true 来确保这个 shell 不会在本行意外退出。

    在条件表达式中使用的文件比较运算符有:

         -e file         file 存在则返回True。
         -d file         file 存在且是一个目录则返回 True。
         -f file         如果 file 存在且是一个普通文件则返回 True。
         -w file         如果 file 存在且可写则返回 True。
         -x file         如果 file 存在且可执行则返回 True。
         file1 -nt file2 如果 file1 比 file2 新则返回 True。(指修改日期)
         file1 -ot file2 如果 file1 比 file2 旧则返回 True。(指修改日期)
         file1 -ef file2 如果两者是相同的设备和具有相同的结点(inode)数则返回 True。
    

    条件表达式中使用的字符串比较运算符有:

              -z str    如果 str 长度为零则返回 True。
              -n str    如果 str 长度为非零则返回 True。
         str1 == str2   如果字符串相等则返回 True。
         str1 =  str2   如果字符串相等则返回 True。
             (使用"=="代替"="符合严格意义上的 POSIX 兼容) 
         str1 != str2   如果字符串不相等则返回 True。
         str1 <  str2   如果 str1 排在 str2 之前则返回 True(与当前位置有关)。
         str1 >  str2   如果 str1 排在 str2 之后则返回 True(与当前位置有关)。
    

    条件表达式中的算术整数比较运算符有-eq-ne-lt-le-gt-ge


    13.2.6 命令行处理

    shell按如下的方式处理脚本:

    • 用这些元字符将其分割成 tokens:SPACE, TAB, NEWLINE, ;, (, ), <, >, |, &

    • 如果不在"..."或'...'内就检查 keyword(循环检查)

    • 如果不在"..."或'...'内就扩展 alias(循环检查)

    • 如果不在"..."或'...'内就扩展 bracea{1,2} -> a1 a2

    • 如果不在"..."或'...'内就扩展 tilde, ~user -> user's home directory

    • 如果不在'...'内就扩展 parameter, $PARAMETER

    • 如果不在'...'内就扩展 command substitution, $(command)

    • 如果不在"..."或'...'内就用 $IFS 分割成 words

    • 如果不在"..."或'...'内就扩展 pathname *?[]

    • 查找 command

      • function

      • built-in

      • file in $PATH

    • 循环

    在双单号内单引号将失效。

    在 shell 里执行 set -x 或者使用 -x 选项调用 shell,该 shell 将会显示出所有执行的命令。 这对调试非常有用。

    March 02

    Linux 关于动态链接库以及静态链接库的一些概念

    库有动态与静态两种
    动态通常用.so为后缀,静态用.a为后缀。例如:libhello.so libhello.a
    为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhello.so.1.0,由于程序连接默认以.so为文件后缀名。所以为了使用这些库,通常使用建立符号连接的方式。
    ln -s libhello.so.1.0 libhello.so.1
    ln -s libhello.so.1 libhello.so
    使用库
    当要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。然而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记‘指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
    现在假设有一个叫hello的程序开发包,它提供一个静态库libhello.a 一个动态库libhello.so,一个头文件hello.h,头文件中提供sayhello()这个函数
    /* hello.h */
    void sayhello();
    另外还有一些说明文档。
    这一个典型的程序开发包结构
    1.与动态库连接
    linux默认的就是与动态库连接,下面这段程序testlib.c使用hello库中的sayhello()函数
    /*testlib.c*/
    #include 
    #include 
    int main()
    {
    sayhello();
    return 0;
    }
    使用如下命令进行编译
    $gcc -c testlib.c -o testlib.o
    用如下命令连接:
    $gcc testlib.o -lhello -o testlib
    在连接时要注意,假设libhello.o 和libhello.a都在缺省的库搜索路径下/usr/lib下,如果在其它位置要加上-L参数
    与与静态库连接麻烦一些,主要是参数问题。还是上面的例子:
    $gcc testlib.o -o testlib -WI,-Bstatic -lhello
    注:这个特别的"-WI,-Bstatic"参数,实际上是传给了连接器ld.
    指示它与静态库连接,如果系统中只有静态库当然就不需要这个参数了。
    如果要和多个库相连接,而每个库的连接方式不一样,比如上面的程序既要和libhello进行静态连接,又要和libbye进行动态连接,其命令应为:
    $gcc testlib.o -o testlib -WI,-Bstatic -lhello -WI,-Bdynamic -lbye
    3.动态库的路径问题
    为了让执行程序顺利找到动态库,有三种方法:
    (1)把库拷贝到/usr/lib和/lib目录下。
    (2)在LD_LIBRARY_PATH环境变量中加上库所在路径。例如动态库libhello.so在/home/ting /lib目录下,以bash为例,使用命令:
    $export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ting/lib
    (3) 修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新。这样,加入的目录下的所有库文件都可见、
    4.查看库中的符号
    有时候可能需要查看一个库中到底有哪些函数,nm命令可以打印出库中的涉及到的所有符号。库既可以是静态的也可以是动态的。nm列出的符号有很多,常见的有三种,一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;一种是库中定义的函数,用T表示,这是最常见的;另外一种是所谓的“弱态”符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。例如,假设开发者希望知道上央提到的hello库中是否定义了 printf():
    $nm libhello.so |grep printf
    U printf
    U表示符号printf被调用,但是并没有在函数内定义,由此可以推断,要正常使用hello库,必须有其它库支持,再使用ldd命令查看hello依赖于哪些库:
    $ldd hello
    libc.so.6=>/lib/libc.so.6(0x400la000)
    /lib/ld-linux.so.2=>/lib/ld-linux.so.2 (0x40000000)
    从上面的结果可以继续查看printf最终在哪里被定义.

    linux静态链接库与动态链接库

    一、引言

    通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为“libxxx.a”的形式。

    其实,我们也可以把对一些库函数的链接载入推迟到程序运行的时期(runtime)。这就是如雷贯耳的动态链接库(dynamic link library)技术。

    二、动态链接库的特点与优势

    首先让我们来看一下,把库函数推迟到程序运行时期载入的好处:

    1. 可以实现进程之间的资源共享。

    什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝;只有没有才链接载入。这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了系统的内存资源。C的标准库就是动态链接库,也就是说系统中所有运行的程序共享着同一个C标准库的代码段。

    2. 将一些程序升级变得简单。用户只需要升级动态链接库,而无需重新编译链接其他原有的代码就可以完成整个程序的升级。Windows 就是一个很好的例子。

    3. 甚至可以真正坐到链接载入完全由程序员在程序代码中控制。

    程序员在编写程序的时候,可以明确的指明什么时候或者什么情况下,链接载入哪个动态链接库函数。你可以有一个相当大的软件,但每次运行的时候,由于不同的操作需求,只有一小部分程序被载入内存。所有的函数本着“有需求才调入”的原则,于是大大节省了系统资源。比如现在的软件通常都能打开若干种不同类型的文件,这些读写操作通常都用动态链接库来实现。在一次运行当中,一般只有一种类型的文件将会被打开。所以直到程序知道文件的类型以后再载入相应的读写函数,而不是一开始就将所有的读写函数都载入,然后才发觉在整个程序中根本没有用到它们。

    三、动态链接库的创建

    由于动态链接库函数的共享特性,它们不会被拷贝到可执行文件中。在编译的时候,编译器只会做一些函数名之类的检查。在程序运行的时候,被调用的动态链接库函数被安置在内存的某个地方,所有调用它的程序将指向这个代码段。因此,这些代码必须实用相对地址,而不是绝对地址。在编译的时候,我们需要告诉编译器,这些对象文件是用来做动态链接库的,所以要用地址不无关代码(Position Independent Code (PIC))。

    对gcc编译器,只需添加上 -fPIC 标签,如:

    gcc -fPIC -c file1.c
    gcc -fPIC -c file2.c
    gcc -shared libxxx.so file1.o file2.o

    注意到最后一行,-shared 标签告诉编译器这是要建立动态链接库。这与静态链接库的建立很不一样,后者用的是 ar 命令。也注意到,动态链接库的名字形式为 “libxxx.so” 后缀名为 “.so”

    四、动态链接库的使用

    使用动态链接库,首先需要在编译期间让编译器检查一些语法与定义。

    这与静态库的实用基本一样,用的是 -Lpath 和 -lxxx 标签。如:

    gcc file1.o file2.o -Lpath -lxxx -o program.exe

    编译器会先在path文件夹下搜索libxxx.so文件,如果没有找到,继续搜索libxxx.a(静态库)。

    在程序运行期间,也需要告诉系统去哪里找你的动态链接库文件。在UNIX下是通过定义名为 LD_LIBRARY_PATH 的环境变量来实现的。只需将path赋值给此变量即可。csh 命令为:

    setenv LD_LIBRARY_PATH   your/full/path/to/dll

    一切安排妥当后,你可以用 ldd 命令检查是否连接正常。

    ldd program.exe

    动态链接库*.so的编译与使用

    动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。
    1、动态库的编译

    下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。

    so_test.h:
    #include
    #include
    void test_a();
    void test_b();
    void test_c();

    test_a.c:
    #include "so_test.h"
    void test_a()
    {
    printf("this is in test_a...\n");
    }

    test_b.c:
    #include "so_test.h"
    void test_b()
    {
    printf("this is in test_b...\n");
    }

    test_a.c:
    #include "so_test.h"
    void test_c()
    {
    printf("this is in test_c...\n");
    }

    将这几个文件编译成一个动态库:libtest.so

    $ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

    2、动态库的链接
    在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。
    test.c:
    #include "so_test.h"
    int main()
    {
    test_a();
    test_b();
    test_c();
    return 0;
    }
    将test.c与动态库libtest.so链接生成执行文件test:
    $ gcc test.c -L. -ltest -o test
    测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
    $ ldd test
    执行test,可以看到它是如何调用动态库中的函数的。
    3、编译参数解析
    最主要的是GCC命令行的一个选项:
    -shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
    -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
    -L.:表示要连接的库在当前目录中
    -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
    LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。
    当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
     
    4、注意
    调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。
    May 01

    FTP命令批量自动下载

    使用FTP下载目录,即FTP命令批量自动下载的bat文件
    该文章转载自1024k:http://www.1024k.cn/os/2007/200704/20692.html
     
    FTP不支持目录的下载,不过FTP命令提供了mget命令,允许多文件下载,但每下载一个文件都需要确认,不能自动完成。本文主要介绍使用批处理,结合FTP的相关命令来实现批量文件的下载,以便达到目录下载的目的。
    大致想法如下:
    ftp -s:filename hosts >result.txt 执行脚本,并将结果定向输出到result.txt
    脚本内容,如
    cd mydir
    ls
    bye
    可以将mydir命令列出
    然后使用批处理分析result.txt
    从150 Opening ASCII mode data connection for file list.的下一行开始算,直到226 Transfer complete都是要下载的内容
    然后用批处理加ftp脚本,使用get命令逐个下载
      但实际过程中发现,在FTP脚本中使用get有问题,提示参数错误,无法使用。
      查看了ftp的帮助ftp -?
    G:>ftp -?
    Transfers files to and from a computer running an FTP server service
    (sometimes called a daemon). Ftp can be used interactively.
    FTP [-v] [-d] [-i] [-n] [-g] [-s:filename] [-a] [-w:windowsize] [-A] [host]
      -v             Suppresses display of remote server responses.
      -n             Suppresses auto-login upon initial connection.
      -i             Turns off interactive prompting during multiple file
                     transfers.
      -d             Enables debugging.
      -g             Disables filename globbing (see GLOB command).
      -s:filename    Specifies a text file containing FTP commands; the
                     commands will automatically run after FTP starts.
      -a             Use any local interface when binding data connection.
      -A             login as anonymous.
      -w:buffersize  Overrides the default transfer buffer size of 4096.
      host           Specifies the host name or IP address of the remotehost to connect to.
    Notes:
      - mget and mput commands take y/n/q for yes/no/quit.
      - Use Control-C to abort commands.
     
    发现 -i 参数可以去除mget的提示,经过测试,实现了如下脚本(使用了匿名登入,如果非匿名,可以修改登入脚本):
    echo cd autoruns>ftp.txt
    echo mget *>>ftp.txt
    echo bye>>ftp.txt
    ftp -i -A -s:ftp.txt 10.1.103.10
       不过,这只是下载了目录中的文件,如果有子目录,那还需要用dir命令输出,并转向输出到文本,用find来提取目录,如:
    echo cd autoruns>ftp.txt
    echo dir>>ftp.txt
    echo bye>>ftp.txt
    ftp -A -s:ftp.txt 10.1.103.10 |find "<DIR>">result.txt
    for /f "tokens=2,3*" %%i in (result.txt) do echo %%k
      如有子文件夹,那就要深入编写了。
      经过编写测试,实现如下脚本,运行环境WINXP SP2,运行通过,未载其它系统上测试过:
    1、主要脚本ftpget.bat,更改前4个变量的相关信息,该脚本调用makeTree.bat,请参见2
    rem FTP服务器地址
    set host=10.1.103.10
    rem FTP登入名,如果匿名不用改
    set user=anonymous
    rem FTP登入密码,如果匿名不用改
    set pass=123456
    rem 需要下载的FTP目录,如果下载子目录以分格
    set dirname=目录1子目录
    set homedir=%cd%
    rem 生成FTP目录结构
    del tree.txt
    start /w cmd /c makeTree %dirname% 0
    del result*.txt
    for /f "delims=/" %%i in (tree.txt) do (
    rem 获取dirname的所有文件
    rem =============================
    cd %homedir%
    md %%i
    cd /d %%i
    echo %user%>ftp.t
    xt
    echo %pass%>>ftp.txt
    echo cd %%i>>ftp.txt
    rem mget *.* 下载所有文件,但不能下载无扩展名的文件;
    rem 如果使用mget * 可以下载所有文件,但会把子目录的文件也下载过来
    echo mget *.*>>ftp.txt
    echo bye>>ftp.txt
    ftp -i -A -s:ftp.txt %host%
    del ftp.txt
    rem ==============================
    )
    cd %homedir%
    del tree.txt
     
    2、maketree.bat,生成FTP目录树
    rem 生成FTP目录结构
    rem 调用方法 maketree dir1dir2 n (n>=1)
    rem %1 == dir1dir2
    rem %2 == n
    set /a treetime=%2+1
    echo %1 >>tree.txt
    echo %user% >ftp%treetime%.txt
    echo %pass% >>ftp%treetime%.txt
    echo cd %1 >>ftp%treetime%.txt
    echo dir >>ftp%treetime%.txt
    echo bye >>ftp%treetime%.txt
    ftp -A -s:ftp%treetime%.txt %host% |find "<DIR>">result%treetime%.txt
    for /f "tokens=2,3*" %%i in (result%treetime%.txt) do (start /w cmd /c Maketree.bat %1%%k %treetime%)
    del result%treetime%.txt
    del ftp%treetime%.txt

      虽然已经实现,但仍然有小问题,就是mget *.* 不能下载无扩展名的程序;如果使用mget * 可以下载所有文件,但会把子目录的文件也下载过来。get在FTP脚本中出错也不知为何。
    January 15

    George, an Artificial Intelligence Avatar

     

    George, an Artificial Intelligence Avatar
    powered by the jabberwacky AI
    created by Icogno and Televirtual
     
    December 14

    改paper

    老板居然这么快把我的draft看完了,赞啊!
     
    除了n多语法,结构上需要改。观点也要改。还有m多小毛病。又得折磨我好几天了。
    December 09

    paper paper

    终于快把第一篇paper的draft写完了,但愿不要被老板狠批,bless~~
     
    还是要庆祝一下的:)
    November 20

    解决WINSOCKS2的怪问题 (转载)

    某台笔记本,ewido杀过木马后,就不正常了,具体表现虽然能PING通,但是在过程中会有点不同
    c:\>ping 10.0.0.1
    Pinging ? with 32 bytes of data:
    Reply from 10.0.0.1: bytes=32 time=12ms TTL=255
    Reply from 10.0.0.1: bytes=32 time=12ms TTL=255
    Reply from 10.0.0.1: bytes=32 time=12ms TTL=255
    Reply from 10.0.0.1: bytes=32 time=12ms TTL=255
     
    问号处本应该是IP
    后来才知道可能是杀木马、病毒过程中WINSOCK2被破坏引起的。
    MS的解决方法:

    症状

    在尝试使用 Ipconfig 程序释放并更新 IP 地址时,您可能会收到以下错误信息:
    An error occurred while renewing interface 'Internet':An operation was attempted on something that is not a socket.
    当您启动 Internet Explorer 时,可能会收到以下错误信息:
    该页无法显示。
    在使用计算机时,可能会收到以下错误信息:
    在 IPMONTR.DLL 中初始化函数 INITHELPERDLL 启动失败,错误代码为 10107
    此外,您可能没有 IP 地址或自动专用 IP 寻址 (APIPA) 地址,并且可能会收到 IP 数据包,但没有发送它们。

    当您使用 ipconfig /renew 命令时,可能会收到以下错误信息。

    消息 1
    An error occurred while renewing interface local area connection:an operation was attempted on something that is not a socket.Unable to contact driver Error code 2.
    消息 2
    The operation failed since no adapter is in the state permissible for this operation.
    消息 3
    The attempted operation is not supported for the type of object referenced.
    在设备管理器中,当您单击“显示隐藏的设备”时,“非即插即用驱动程序”下面的列表中停用“TCP/IP Protocol Driver”,并收到错误代码 24。

    当您创建拨号连接时,可能会收到以下错误信息:
    Error 720:No PPP Control Protocols Configured
     

    原因

    如果 WinSocks 注册表项损坏,则可能出现这些问题。
     

    解决方案

    如何确定 Winsock2 注册表项是否损坏

    要确定症状是否由 Winsock2 注册表项的问题引起,请使用以下方法。

    方法 1:使用 Netdiag 工具

    要使用 Netdiag 工具,您必须安装 Microsoft Windows XP 支持工具。为此,请按照下列步骤操作。

    注意:
    如果已经安装了支持工具,请直接执行本部分的第二步。
    如果未安装支持工具并且没有 Windows XP 安装 CD,请转到“方法 2”。
    1. 插入 Windows XP 安装 CD,然后找到 Support\Tools 文件夹。
    2. 双击“Setup.exe”文件。
    3. 按照屏幕上的步骤操作,直至看到“请选择安装类型”屏幕。
    4. 在“请选择安装类型”屏幕上,单击“完全”,然后单击“下一步”。
    安装完成后,请按照下列步骤操作:
    1. 单击“开始”,单击“运行”,键入 Command,然后单击“确定”。
    2. 键入 netdiag /test:winsock,然后按 Enter。
    Netdiag 工具将返回若干网络组件(包括 Winsock)的测试结果。要了解该测试的更多详细信息,请在以下 netdiag 命令结尾处添加 /vnetdiag /test:winsock /v

    方法 2:使用 Msinfo32 程序

    注意:只有在没有 Windows XP 安装 CD 并且未安装支持工具时,才应使用此方法。
    1. 单击“开始”,单击“运行”,键入“Msinfo32”,然后单击“确定”。
    2. 展开“组件”,展开“网络”,然后单击“协议”。
    3. “协议”下有 10 个节。如果 Winsock2 注册表项未损坏,则节标头应包含以下名称:
    MSAFD Tcpip [TCP/IP]
    MSAFD Tcpip [UDP/IP]
    RSVP UDP Service Provider
    RSVP TCP Service Provider
    MSAFD NetBIOS [\Device\NetBT_Tcpip...
    MSAFD NetBIOS [\Device\NetBT_Tcpip...
    MSAFD NetBIOS [\Device\NetBT_Tcpip...
    MSAFD NetBIOS [\Device\NetBT_Tcpip...
    MSAFD NetBIOS [\Device\NetBT_Tcpip...
    MSAFD NetBIOS [\Device\NetBT_Tcpip...
    如果名称与此列表中的内容有任何不同,则说明 Winsock2 注册表项已经损坏,或者您安装了第三方加载项(如代理服务器软件)。
    如果安装了第三方加载项,则加载项的名称将替换列表中的字母“MSAFD”。

    如果列表的内容超过 10 个节,则说明安装了第三方加载项。

    如果少于 10 个节,则说明缺少信息。

    注意:这些条目所代表的是仅装有 TCP/IP 协议的安装。您可能有一个正在工作的 Winsock,如果安装了另一个协议,则可能会看到其他条目。例如,如果安装 NWLink IPX/SPX,您将另外看到 7 个节,也就是总共 17 个节。下面的示例展示了一个新的节标头:
    MSAFD nwlnkipx [IPX]
    通过安装 NWLink IPX/SPX 创建的每个新节也以“MSAFD”开头。因此,仍然只有两个不以这些字母开头的节。

    如果 Netdiag 测试失败,或者,如果通过查看 Msinfo32 信息确定了 Winsock 的损坏,您必须使用下一部分的步骤修复 Winsock2 注册表项。
     

    如何恢复损坏的 Winsock2

    带 Service Pack 2 的 Windows XP

    要在安装了 Windows XP Service Pack 2 (SP2) 的情况下修复 Winsock,请在命令提示符处键入 netsh winsock reset,然后按 Enter。

    注意:运行此命令后请重新启动计算机。此外,对于运行 Windows XP SP2 的计算机,还有一个新的 netsh 命令可用于重新构建 Winsock 注册表项。有关更多信息,请访问下面的网站:
    http://www.microsoft.com/china/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx (http://www.microsoft.com/china/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx)
    警告:在运行 netsh winsock reset 命令时,访问或监视 Internet 的程序(如防病毒程序、防火墙或代理客户端)可能会受到不良影响。如果执行此解决方案后某个程序无法正常工作,请重新安装该程序以恢复功能。

    注意:如果这些步骤都无法解决问题,请执行下一部分的步骤。

    不带 Service Pack 2 的 Windows XP

    如果要在未安装 Windows XP SP2 的情况下修复 Winsock,请删除损坏的注册表项,然后重新安装 TCP/IP 协议。
    第 1 步:删除损坏的注册表项
    警告:如果使用注册表编辑器或其他方法错误地修改了注册表,有可能会导致严重问题。这些问题可能需要重新安装操作系统才能解决。Microsoft 不能保证可以解决这些问题。修改注册表需要您自担风险。

    有关如何备份注册表的更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    322756 (http://support.microsoft.com/kb/322756/) 如何在 Windows XP 和 Windows Server 2003 中备份、编辑和还原注册表
    1. 单击“开始”,然后单击“运行”。
    2. 在“打开”框中,键入“regedit”,然后单击“确定”。
    3. 在注册表编辑器中,找到以下注册表项,右键单击每一项,然后单击“删除”:
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock2
    4. 当提示您确认删除时,单击“是”。
    注意:删除 Winsock 注册表项后请重新启动计算机。这样做可以让 Windows XP 操作系统为这两个注册表项创建新的 shell 条目。如果在删除 Winsock 注册表项后未重新启动计算机,则下一步将无法正常进行。
    第 2 步:安装 TCP/IP
    1. 右键单击网络连接,然后单击“属性”。
    2. 单击“安装”。
    3. 单击“协议”,然后单击“添加”。
    4. 单击“从磁盘安装”。
    5. 键入 C:\Windows\inf,然后单击“确定”。
    6. 在可用协议列表中,单击“Internet 协议 (TCP/IP)”,然后单击“确定”。
    7. 重新启动计算机。
    November 17

    PBS基本完成

    至少可以用了,我跑了几天的程序,一切正常。
    但是需要注意一些细节,今天重启了一下server导致程序混乱,只好手动del掉,重新run一遍。忘了可以在线配置的。这样应该就没有什么问题了。
     
    下午写个文档,发布一下:)
    November 15

    PBS初见成效

    终于把PBS配置完毕,昨天用自己的程序测试了一下,到现在还没有出错。
     
    让他go on吧。
     
    但是美中不足的是,PBS不能自动监测cpu的使用情况,如果用户用非PBS的方式提交作业,PBS可能重复提交。很讨厌,这样不能充分利用资源,反而导致速度下降。想个解决的方案吧。