Chinaunix首页 | 论坛 | 博客
  • 博客访问: 336256
  • 博文数量: 106
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 861
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-10 08:32
文章分类

全部博文(106)

文章存档

2016年(11)

2015年(93)

2013年(2)

分类: C/C++

2015-08-21 15:03:35

linux中getopt的用法

getopt被用来解析命令行选项参数。就不用自己写东东处理argv了。

#include <unistd.h>
       extern char *optarg;   //选项的参数指针
       extern int optind,    //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。 
       extern int opterr,   //当opterr=0时,getopt不向stderr输出错误信息。
       extern int optopt;   //当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt中,getopt返回'?’、
       int getopt(int argc, char * const argv[], const char *optstring);
调用一次,返回一个选项。 在命令行选项参数再也检查不到optstring中包含的选项时,返回-1,同时optind储存第一个不包含选项的命令行参数。

首先说一下什么是选项,什么是参数。

字符串optstring可以下列元素,
1.单个字符,表示选项,
2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。
3 单个字符后跟两个冒号,表示该选项后必须跟一个参数。参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(这个特性是GNU的扩张)。

getopt处理以'-’开头的命令行参数,如optstring="ab:c::d::",命令行为getopt.exe -a -b host -ckeke -d haha 
在这个命令行参数中,-a和-h就是选项元素,去掉'-',a,b,c就是选项。host是b的参数,keke是c的参数。但haha并不是d的参数,因为它们中间有空格隔开。

还要注意的是默认情况下getopt会重新排列命令行参数的顺序,所以到最后所有不包含选项的命令行参数都排到最后。
如getopt.exe -a ima -b host -ckeke -d haha, 都最后命令行参数的顺序是: -a -b host -ckeke -d ima haha
如果optstring中的字符串以'+'加号开头或者环境变量POSIXLY_CORRE被设置。那么一遇到不包含选项的命令行参数,getopt就会停止,返回-1。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int result;

    opterr = 0; //使getopt不行stderr输出错误信息

    while( (result = getopt(argc, argv, "ab:c::")) != -1 )
    {
           switch(result)
          {
              case 'a':
                  printf("option=a, optopt=%c, optarg=%s\n", optopt, optarg);
                  break;
              case 'b':
                   printf("option=b, optopt=%c, optarg=%s\n", optopt, optarg);
                   break;
              case 'c':
                  printf("option=c, optopt=%c, optarg=%s\n", optopt, optarg);
                    break;
              case '?':
                    printf("result=?, optopt=%c, optarg=%s\n", optopt, optarg);
                    break;
            default:
                  printf("default, result=%c\n",result);
                  break;
          }
       printf("argv[%d]=%s\n", optind, argv[optind]);
    }
    printf("result=-1, optind=%d\n", optind);   //看看最后optind的位置

    for(result = optind; result < argc; result++)
         printf("-----argv[%d]=%s\n", result, argv[result]);

//看看最后的命令行参数,看顺序是否改变了哈。
    for(result = 1; result < argc; result++)
         printf("\nat the end-----argv[%d]=%s\n", result, argv[result]);
    return 0;
}

unistd里有个 optind 变量,每次getopt后,这个索引指向argv里当前分析的字符串的下一个索引,因此
argv[optind]就能得到下个字符串,通过判断是否以 '-'开头就可。


getopt()函数就是用来解析命令行参数

调用形式一般如下:
  1. while((c = getopt(argc, argv, "xy:z::")) != -1){
  2.       switch(c){
  3.       case 'x':   ... ...
  4.       case 'y':   ... ...
  5.       case 'z':   ... ...
  6.       ... ....
  7.       }
  8. }
  9. ... ....
getopt函数的原型如下:
  1. #include <unistd.h>
  2. int getopt(int argc, char * const argv[], const char *optstring);
  3. extern char *optarg; 
    extern int optind,  // 初始化值为1,下一次调用getopt时,从optind存储的位置重新开始检查选项。 
    extern int opterr,  // 初始化值为1,当opterr=0时,getopt不向stderr输出错误信息。
    extern int optopt;  // 当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,
                                        // 该选项存储在optopt中, getopt返回'?’。
getopt()函数用于解析命令行参数。

optarg和optind是两个最重要的external 变量。optarg是指向参数的指针(当然这只针对有参数的选项);
optind是argv[]数组的索引,众所周知,argv[0]是函数名称,所有参数从argv[1]开始,所以optind被初始化设置指为1。       
每调用一次getopt()函数,返回一个选项,如果该选项有参数,则optarg指向该参数。
 在命令行选项参数再也检查不到optstring中包含的选项时,返回-1。
字符串optstring,它是作为选项的字符串的列表。
函数getopt()认为optstring中,以'-’开头的字符(注意!不是字符串!!)就是命令行参数选项,
有的参数选项后面可以跟参数值。optstring中的格式规范如下:
1) 单个字符,表示选项,
2) 单个字符后接一个冒号”:”,表示该选项后必须跟一个参数值。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。
3) 单个字符后跟两个冒号”::”,表示该选项后必须跟一个参数。参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。
getopt()函数的第三个参数optstring是一个有所有合法的“可选字符”所组成的字符串。
《1》在参数optstring的“可选字符”如果后面带有一个':',则表示在该“可选字符”的后面必须有一个参数。
比如“o:"表示: gcc -o arg 在-o的后面必须带有一个参数arg. 在getopt()函数解析完"o:"对应的命令行参数时,char型的指针optarg则指向了参数"arg"。
《2》如果在“可选字符”的后面带有了两个':'时,则表示在该“可选字符”后面可能有也可能没有参数,有参数,则optarg指向参数,没有则为0。这是GNU的一个关于getopt()函数的扩展。
《3》如果optstring中含有一个大写的'W'字符,后面带有一个冒号,也就是形如"W:",则表示该“可选字符”是一个“长选项”,也就是说不是只有一个字符的“可选字符”。比如:gcc -Wall  hello.c 要解析该命令行,getopt()函数中的第三个参数optstring应该是:"W:all",而且当解析到“-Wall"时optarg = "all".  这一点也是GNU对getopt()函数的扩展。
《4》如果getopt()函数在argv中解析到一个没有包含在optstring中的“可选字符”,它会打印一个错误信息,并将该“可选字符”保存在optopt中,并返回字符'?'。当然,我们可以将变量opterr赋值为0,来阻止getopt()函数输出错误信息。
《5》当getopt()函数的第三个参数optstring的第一个字符是':'时,很显然,这是由于少写了一个"可选字符"的缘故。此时,getopt()函数不返回'?',而是返回':'来暗示我们漏掉了一个”可选字符”.

    1. <SPAN style="FONT-SIZE: 14px">#include <stdio.h>  
    2. #include <stdlib.h>   
    3. #include <unistd.h>   
    4. #include <fcntl.h>   
    5. int main(int argc, char *argv[])  
    6. {  
    7.         int c;  
    8.         opterr = 0;   
    9.         while((c = getopt(argc, argv, "Oo:W:all")) != -1){  
    10.                 printf("option char: %c\n", c);  
    11.                 switch(c){  
    12.                 case 'O':  
    13.                         printf("optimization flag is open.\n\n");  
    14.                         break;  
    15.                 case 'o':  
    16.                         printf("the obj is: %s\n\n", optarg);  
    17.                         break;  
    18.                 case 'W':  
    19.                         printf("optarg: %s\n\n", optarg);  
    20.                         break;          
    21.                 case '?':  
    22.                         fprintf(stderr, "Usage: %s [-Wall] [-O] [-o arg] arg\n", argv[0]);  
    23.                         break;  
    24.                 case ':':  
    25.                         fprintf(stderr, "miss option char in optstring.\n");  
    26.                         break;  
    27.                 }  
    28.         }  
    29.         exit(0);  
    30. }</SPAN>  
    编译:gcc -Wall -o mygcc gcc.c
    运行:./mygcc -Wall -O -o mygcc
    结果:
    option char: W
    optarg: all

    option char: O
    optimization flag is open.

    option char: o
    the obj is: mygcc
    1. <SPAN style="FONT-SIZE: 14px">#include <stdio.h>  
    2. #include <stdlib.h>   
    3. #include <unistd.h>   
    4. #include <fcntl.h>   
    5. int main(int argc, char *argv[])  
    6. {  
    7.         int c;  
    8.   
    9.         // opterr = 0;    
    10.         while((c = getopt(argc, argv, "iu:z:")) != -1){  
    11.               switch(c){  
    12.               case 'i':  
    13.                  printf("current option index:(optind-1)=%d, argv[optind-1]=argv[%d]=%s\n",  
    14.                                 (optind-1), (optind-1), argv[optind-1]);  
    15.                  printf("next option index:(optind)=%d, argv[optind]=argv[%d]=%s\n",  
    16.                                 (optind), (optind), argv[optind]);  
    17.                  printf("optarg=%s, opterr=%d, optopt=%d\n\n", optarg, opterr, optopt);  
    18.                  break;  
    19.   
    20.              case 'u':  
    21.                  printf("current option index:(optind-2)=%d, argv[optind-2]=argv[%d]=%s\n",  
    22.                                 (optind-2), (optind-2), argv[optind-2]);  
    23.                  printf("next option index:(optind)=%d, argv[optind]=argv[%d]=%s\n",  
    24.                                 (optind), (optind), argv[optind]);  
    25.                  printf("optarg=%s, opterr=%d, optopt=%d\n\n", optarg, opterr, optopt);  
    26.                  break;  
    27.   
    28.              case 'z':  
    29.                  printf("current option index:(optind-1)=%d, argv[optind-1]=argv[%d]=%s\n",  
    30.                                 (optind-1), (optind-1), argv[optind-1]);  
    31.                  printf("next option index:(optind)=%d, argv[optind]=argv[%d]=%s\n",  
    32.                                 (optind), (optind), argv[optind]);  
    33.                  printf("optarg=%s, opterr=%d, optopt=%d\n\n", optarg, opterr, optopt);  
    34.                  break;  
    35.   
    36.              case '?':  
    37.                  fprintf(stderr, "Usage: %s [-i] [-u username] [-z filename]\n", argv[0]);  
    38.                  break;  
    39.                 }  
    40.         }  
    41.         exit(0);  
    42. }</SPAN>  
    编译:gcc -Wall -o getopt2 getopt2.c
    运行:./getopt2 -i -u username -z filename
    结果:
    current option index:(optind-1)=1, argv[optind-1]=argv[1]=-i
    next option index:(optind)=2, argv[optind]=argv[2]=-u
    optarg=(null), opterr=1, optopt=0

    current option index:(optind-2)=2, argv[optind-2]=argv[2]=-u
    next option index:(optind)=4, argv[optind]=argv[4]=-z
    optarg=username, opterr=1, optopt=0

    current option index:(optind-1)=5, argv[optind-1]=argv[5]=filename
    next option index:(optind)=6, argv[optind]=argv[6]=(null)
    optarg=filename, opterr=1, optopt=0


    getopt:命令行选项、参数处理

    在写shell脚本时经常会用到命令行选项、参数处理方式,如:

    ./test.sh -f config.conf -v --prefix=/home

    -f 为短选项,它需要一个参数,即config.conf, -v也是一个选项,但它不需要参数
    –prefix 是一个长选项,即选项本身多于一个字符,它也需要一个参数,用等号连接,当然等号不是必须的,/home可以直接写在–prefix后面,即–prefix=/home

    在shell中,可以用以下三种方式来处理命令行参数,每种方式都有自己的应用场景

    • 手工处理方式
    • getopts
    • getopt

    下面我们依次讨论这三种处理方式

    1. 手工处理方式
    在手工处理方式中,首先要知道几个变量,还是以上面的命令行为例:

    $0 : ./test.sh,即命令本身,相当于C/C++中的argv[0]
    $1 : -f,第一个参数
    $2 : config.conf
    $3, $4 … :类推。
    $#  : 参数的个数,不包括命令本身,上例中$#为4.
    $@ : 参数本身的列表,也不包括命令本身,如上例为 -f config.conf -v –prefix=/home
    $*   : 和$@相同,但”$*” 和 “$@”(加引号)并不同,”$*”将所有的参数解释成一个字符串,而”$@”是一个参数数组。如下例所示:

    #!/bin/bash for arg in "$*" do echo $arg done echo for arg in "$@" do echo $arg done
    $ bash test.sh -f config.conf -v --prefix=/home -f config.conf -v --prefix=/home #这是"$*"的输出 -f #以下为$@的输出 config.conf -v --prefix=/home

    所以,手工处理的方式即对这些变量的处理。因为手工处理高度依赖于你在命令行上所传参数的位置,所以一般都只用来处理较简单的参数。如./test.sh 10。而很少使用./test -n 10这种带选项的方式。

    手工处理方式能满足大多数的简单需求,配合shift使用也能构造出强大的功能,但在要处理复杂选项的时候建议用下面的两种方法。

    2. getopts/getopt
    处理命令行参数是一个相似而又复杂的事情,在shell中,处理此事的是getopts和getopt

    getopts和getopt功能相似但又不完全相同,其中getopt是独立的可执行文件,而getopts是由bash内置的

    先来看看参数传递的典型用法:

    ./test.sh -a -b -c  : 短选项,各选项不需参数
    ./test.sh -abc   : 短选项,和上一种方法的效果一样,只是将所有的选项写在一起。
    ./test.sh -a args -b -c :短选项,其中-a需要参数,而-b -c不需参数。
    ./test.sh –a-long=args –b-long :长选项

    我们先来看getopts,它不支持长选项。使用getopts非常简单:

    #!/bin/bash while getopts "a:bc" arg #选项后面的冒号表示该选项需要参数 do case $arg in a) echo "a's arg:$OPTARG" #参数存在$OPTARG中 ;; b) echo "b" ;; c) echo "c" ;; ?) #当有不认识的选项的时候arg为? echo "unkonw argument" exit 1 ;; esac done
    $ bash test.sh -a arg -b -c
    a's arg:arg
    b
    c
    $ bash test.sh -a arg -bc
    a's arg:arg
    b
    c

    应该说绝大多数脚本使用该函数就可以了,如果需要支持长选项以及可选参数,那么就需要使用getopt

    #!/bin/bash #-o表示短选项,两个冒号表示该选项有一个可选参数,可选参数必须紧贴选项 #如-carg 而不能是-c arg #--long表示长选项 #"$@"在上面解释过 # -n:出错时的信息 # -- :举一个例子比较好理解: #我们要创建一个名字为 "-f"的目录你会怎么办? # mkdir -f #不成功,因为-f会被mkdir当作选项来解析,这时就可以使用 # mkdir -- -f 这样-f就不会被作为选项。 TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
         -n 'example.bash' -- "$@"` if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi # Note the quotes around `$TEMP': they are essential! #set 会重新排列参数的顺序,也就是改变$1,$2...$n的值,这些值在getopt中重新排列过了 eval set -- "$TEMP" #经过getopt的处理,下面处理具体选项。 while true ; do case "$1" in -a|--a-long) echo "Option a" ; shift ;; -b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;; -c|--c-long) # c has an optional argument. As we are in quoted mode, # an empty parameter will be generated if its optional # argument is not found. case "$2" in "") echo "Option c, no argument"; shift 2 ;; *) echo "Option c, argument \`$2'" ; shift 2 ;; esac ;; --) shift ; break ;; *) echo "Internal error!" ; exit 1 ;; esac done echo "Remaining arguments:" for arg do echo '--> '"\`$arg'" ; done
    $ bash test.sh -a -b arg arg1 -c Option a Option b, argument `arg'
    Option c, no argument
    Remaining arguments:
    --> `arg1'

    可以看到,命令行中多了个arg1参数,在经过getopt和set之后,命令行会变为:
    -a -b arg -c — arg1
    $1指向-a,$2指向-b,$3指向arg,$4指向-c,$5指向–,而多出的arg1则被放到了最后

    3. 举例
    如将前面的ssh.expscp.exp封装起来,代码:

    #!/bin/bash ######################  proc defination  ######################## # ignore rule ignore_init() { # ignore password array_ignore_pwd_length=0 if [ -f ./ignore_pwd ]; then while read IGNORE_PWD do array_ignore_pwd[$array_ignore_pwd_length]=$IGNORE_PWD
                            let array_ignore_pwd_length=$array_ignore_pwd_length+1 done < ./ignore_pwd fi # ignore ip address array_ignore_ip_length=0 if [ -f ./ignore_ip ]; then while read IGNORE_IP do array_ignore_ip[$array_ignore_ip_length]=$IGNORE_IP
                            let array_ignore_ip_length=$array_ignore_ip_length+1 done < ./ignore_ip fi } show_version() { echo "version: 1.0" echo "updated date: 2014-01-09" } show_usage() { echo -e "`printf %-16s "Usage: $0"` [-h|--help]" echo -e "`printf %-16s ` [-v|-V|--version]" echo -e "`printf %-16s ` [-l|--iplist ... ]" echo -e "`printf %-16s ` [-c|--config ... ]" echo -e "`printf %-16s ` [-t|--sshtimeout ... ]" echo -e "`printf %-16s ` [-T|--fttimeout ... ]" echo -e "`printf %-16s ` [-L|--bwlimit ... ]" echo -e "`printf %-16s ` [-n|--ignore]" #echo "ignr_flag: 'ignr'-some ip will be ignored; otherwise-all ip will be handled" } # Default Parameters myIFS=":::" # 配置文件中的分隔符 TOOLDIR=/root/scripts
    cd $TOOLDIR
    
    IPLIST="iplist.txt" # IP列表,格式为IP 端口 用户名 密码 CONFIG_FILE="config.txt" # 命令列表和文件传送配置列表,关键字为com:::和file::: IGNRFLAG="noignr" # 如果置为ignr,则脚本会进行忽略条件的判断 SSHTIMEOUT=100 # 远程命令执行相关操作的超时设定,单位为秒 SCPTIMEOUT=2000 # 文件传送相关操作的超时设定,单位为秒 BWLIMIT=1024000 # 文件传送的带宽限速,单位为kbit/s # 入口参数分析 TEMP=`getopt -o hvVl:c:t:T:L:n --long help,version,iplist:,config:,sshtimeout:,fttimeout:,bwlimit:,ignore -- "$@" 2>/dev/null` [ $? != 0 ] && echo -e "\033[31mERROR: unknown argument! \033[0m\n" && show_usage && exit 1 # 会将符合getopt参数规则的参数摆在前面,其他摆在后面,并在最后面添加-- eval set -- "$TEMP" while : do [ -z "$1" ] && break; case "$1" in -h|--help) show_usage; exit 0 ;; -v|-V|--version) show_version; exit 0 ;; -l|--iplist) IPLIST=$2; shift 2 ;; -c|--config) CONFIG_FILE=$2; shift 2 ;; -t|--sshtimeout) SSHTIMEOUT=$2; shift 2 ;; -T|--fttimeout) SCPTIMEOUT=$2; shift 2 ;; -L|--bwlimit) BWLIMIT=$2; shift 2 ;; -n|--ignore) IGNRFLAG="ignr"; shift ;; --) shift ;; *) echo -e "\033[31mERROR: unknown argument! \033[0m\n" && show_usage && exit 1 ;; esac done ################  main  ####################### BEGINDATETIME=`date "+%F %T"` [ ! -f $IPLIST ] && echo -e "\033[31mERROR: iplist \"$IPLIST\" not exists, please check! \033[0m\n" && exit 1 [ ! -f $CONFIG_FILE ] && echo -e "\033[31mERROR: config \"$CONFIG_FILE\" not exists, please check! \033[0m\n" && exit 1 echo
    echo "You are using:" echo -e "`printf %-16s "\"$CONFIG_FILE\""` ---- as your config" echo -e "`printf %-16s "\"$IPLIST\""` ---- as your iplist" echo -e "`printf %-16s "\"$SSHTIMEOUT\""` ---- as your ssh timeout" echo -e "`printf %-16s "\"$SCPTIMEOUT\""` ---- as your scp timeout" echo -e "`printf %-16s "\"$BWLIMIT\""` ---- as your bwlimit" echo -e "`printf %-16s "\"$IGNRFLAG\""` ---- as your ignore flag" echo [ -f ipnologin.txt ] && rm -f ipnologin.txt
    IPSEQ=0 while read IP PORT USER PASSWD PASSWD_2ND PASSWD_3RD PASSWD_4TH OTHERS do [ -z "`echo $IP | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'`" ] && continue [ "`python $TOOLDIR/ckssh.py $IP $PORT`" == 'no' ] && echo "$IP" >> ipnologin.txt && continue let IPSEQ=$IPSEQ+1 # 如果启用了忽略,则进入忽略流程 if [ $IGNRFLAG == "ignr" ]; then ignore_init
                    ignored_flag=0 i=0 while [ $i -lt $array_ignore_pwd_length ] do [ ${PASSWD}x == ${array_ignore_pwd[$i]}x ] && ignored_flag=1 && break let i=$i+1 done [ $ignored_flag -eq 1 ] && continue j=0 while [ $j -lt $array_ignore_ip_length ] do [ ${IP}x == ${array_ignore_ip[$j]}x ] && ignored_flag=1 && break let j=$j+1 done [ $ignored_flag -eq 1 ] && continue fi ####### Try password from here #### for PW in $PASSWD $PASSWD_2ND $PASSWD_3RD $PASSWD_4TH do PASSWD_USE=$PW
                    $TOOLDIR/ssh.exp $IP $USER $PW $PORT true $SSHTIMEOUT [ $? -eq 0 ] && PASSWD_USE=$PW && break done # 针对一个$IP,执行配置文件中的一整套操作 while read eachline do # 必须以com或file开头 [ -z "`echo $eachline | grep -E '^com|^file'`" ] && continue myKEYWORD=`echo $eachline | awk -F"$myIFS" '{ print $1 }'` myCONFIGLINE=`echo $eachline | awk -F"$myIFS" '{ print $2 }'` # 对配置文件中的预定义的可扩展特殊字符串进行扩展 # 关键字#IP#,用$IP进行替换 if [ ! -z "`echo "$myCONFIGLINE" | grep '#IP#'`" ]; then myCONFIGLINE_temp=`echo $myCONFIGLINE | sed "s/#IP#/$IP/g"` myCONFIGLINE=$myCONFIGLINE_temp fi # 时间相关关键字,用当前时间进行替换 if [ ! -z "`echo "$myCONFIGLINE" | grep '#YYYY#'`" ]; then myYEAR=`date +%Y` myCONFIGLINE_temp=`echo $myCONFIGLINE | sed "s/#YYYY#/$myYEAR/g"` myCONFIGLINE=$myCONFIGLINE_temp fi if [ ! -z "`echo "$myCONFIGLINE" | grep '#MM#'`" ]; then myMONTH=`date +%m` myCONFIGLINE_temp=`echo $myCONFIGLINE | sed "s/#MM#/$myMONTH/g"` myCONFIGLINE=$myCONFIGLINE_temp fi if [ ! -z "`echo "$myCONFIGLINE" | grep '#DD#'`" ]; then myDATE=`date +%d` myCONFIGLINE_temp=`echo $myCONFIGLINE | sed "s/#DD#/$myDATE/g"` myCONFIGLINE=$myCONFIGLINE_temp fi if [ ! -z "`echo "$myCONFIGLINE" | grep '#hh#'`" ]; then myHOUR=`date +%H` myCONFIGLINE_temp=`echo $myCONFIGLINE | sed "s/#hh#/$myHOUR/g"` myCONFIGLINE=$myCONFIGLINE_temp fi if [ ! -z "`echo "$myCONFIGLINE" | grep '#mm#'`" ]; then myMINUTE=`date +%M` myCONFIGLINE_temp=`echo $myCONFIGLINE | sed "s/#mm#/$myMINUTE/g"` myCONFIGLINE=$myCONFIGLINE_temp fi if [ ! -z "`echo "$myCONFIGLINE" | grep '#ss#'`" ]; then mySECOND=`date +%S` myCONFIGLINE_temp=`echo $myCONFIGLINE | sed "s/#ss#/$mySECOND/g"` myCONFIGLINE=$myCONFIGLINE_temp fi # IPSEQ关键字,用当前IP的序列号替换,从1开始 if [ ! -z "`echo "$myCONFIGLINE" | grep '#IPSEQ#'`" ]; then myCONFIGLINE_temp=`echo $myCONFIGLINE | sed "s/#IPSEQ#/$IPSEQ/g"` myCONFIGLINE=$myCONFIGLINE_temp fi # 配置文件中有关键字file:::,就调用scp.exp进行文件传送 if [ "$myKEYWORD"x == "file"x ]; then SOURCEFILE=`echo $myCONFIGLINE | awk '{ print $1 }'` DESTDIR=`echo $myCONFIGLINE | awk '{ print $2 }'` DIRECTION=`echo $myCONFIGLINE | awk '{ print $3 }'` $TOOLDIR/scp.exp $IP $USER $PASSWD_USE $PORT $SOURCEFILE $DESTDIR $DIRECTION $BWLIMIT $SCPTIMEOUT [ $? -ne 0 ] && echo -e "\033[31mSCP Try Out All Password Failed\033[0m\n" # 配置文件中有关键字com:::,就调用ssh.exp进行远程命令执行 elif [ "$myKEYWORD"x == "com"x ]; then $TOOLDIR/ssh.exp $IP $USER $PASSWD_USE $PORT "${myCONFIGLINE}" $SSHTIMEOUT [ $? -ne 0 ] && echo -e "\033[31mSSH Try Out All Password Failed\033[0m\n" else echo "ERROR: configuration wrong! [$eachline] " echo "       where KEYWORD should not be [$myKEYWORD], but 'com' or 'file'" echo "       if you dont want to run it, you can comment it with '#'" echo "" exit fi done < $CONFIG_FILE done < $IPLIST
    
    ENDDATETIME=`date "+%F %T"` echo "$BEGINDATETIME -- $ENDDATETIME" echo "$0 $* --excutes over!" exit 0

    参考:http://www.cnblogs.com/FrankTan/archive/2010/03/01/1634516.html



阅读(906) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~