欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

马哥 31_02 _bash脚本编程之在bash脚本中使用选项 有大用

# !/bin/bash

# name:

# description:

# version: 0.0.1     #主版本号0,次版本号0.发行号(修正号)1

# author: magedu

# datetime: 


生成文件首部的文件





[root@mail scripts]# vim mkscript

#!/bin/bash

# Name: mkscript

# Description: Create script

# Author: Magedu

# Datatime: 03/02/12 14:42:00

# Usage: mkscript FILENAME

cat > $1 << EOF

#!/bin/bash

# Name: `basename $1`

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: `date +"%F %T"`

# Usage: `basename $1`


EOF


vim +8 $1   # 这目的是vim 跳到 第8行



[root@mail scripts]# chmod +x mkscript

[root@mail scripts]#





[root@mail scripts]# ./mkscript test.sh  # 执行的结果就是这样

#!/bin/bash

# Name: test.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 10:18:01

# Usage: test.sh



root@mail scripts]# cp /etc/fstab ./   

[root@mail scripts]# ./mkscript fstab   #可以看到 fstab 被清空了

#!/bin/bash

# Name: fstab

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 10:22:41

# Usage: fstab



"fstab" 8L, 123C 



[root@mail scripts]# vim mkscript

#!/bin/bash

# Name: mkscript

# Description: Create script

# Author: Magedu

# Datatime: 03/02/12 14:42:00

# Usage: mkscript FILENAME

if ! grep "[^[:space:]]" $1 &> /dev/null; then  # 判断如果文件为空,才添加文件首部

cat > $1 << EOF

#!/bin/bash

# Name: `basename $1`

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: `date +"%F %T"`

# Usage: `basename $1`


EOF


fi


vim + $1  # 打开 到文件的最后一行



[root@mail scripts]# \cp  -f /etc/fstab ./  再拷贝一次过来

[root@mail scripts]#



[root@mail scripts]# ./mkscript fstab  # 此时文件里面的内容没动

/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1

LABEL=/boot             /boot                   ext3    defaults        1 2

tmpfs                   /dev/shm                tmpfs   defaults        0 0

devpts                  /dev/pts                devpts  gid=5,mode=620  0 0

sysfs                   /sys                    sysfs   defaults        0 0

proc                    /proc                   proc    defaults        0 0

/dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0

//192.168.1.75/tools   /mnt                     cifs    credentials=/etc/samba/cred.passwd 0 0


[root@mail scripts]# vim mkscript    #当空文件时,就添加首部,非空文件时,就直接vim打开文件

#!/bin/bash

# Name: mkscript

# Description: Create script

# Author: Magedu

# Datatime: 03/02/12 14:42:00

# Usage: mkscript FILENAME

if ! grep "[^[:space:]]" $1 &> /dev/null; then

cat > $1 << EOF

#!/bin/bash

# Name: `basename $1`

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: `date +"%F %T"`

# Usage: `basename $1`


EOF


fi


vim + $1


until bash -n $1 &> /dev/null; do        # 如果有问题,就执行下面 重新打开这个文件

  echo "Syntax error:"

  vim + $1

done;


chmod +x $1        

# 给它执行权限




[root@mail scripts]# ./mkscript a.sh   # 出错,无法保存,但是看不到出错信息了

#!/bin/bash

# Name: a.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 13:00:29

# Usage: a.sh

if id rehat; then

  echo "hello"




[root@mail scripts]# ./mkscript a.sh

Syntax error:

#!/bin/bash

# Name: a.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 13:00:29

# Usage: a.sh

if id rehat; then

  echo "hello"

fi



[root@mail scripts]# ./mkscript a.sh  #保存后,才看到错

Syntax error:

[root@mail scripts]#



[root@mail scripts]# vim mkscript

# Datetime: `date +"%F %T"`

# Usage: `basename $1`


EOF


fi


vim + $1


until bash -n $1 &> /dev/null; do

  read -p "Syntax error, q|Q for quiting,others for editing: " OPT   # read 函数,与用户交互,用户的输入保存在OPT变量里面

  case $OPT in

    q|Q)

        echo "Quit."

        exit 8;;

    *)

        vim + $1;;

  esac

done;


chmod +x $1




[root@mail scripts]# ./mkscript a.sh   # 删除最后的 fi,然后保存

#!/bin/bash

# Name: a.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 13:00:29

# Usage: a.sh

if id rehat; then

  echo "hello"

~



Syntax error, q|Q for quiting,others for editing:      # 直接回车,打开继续编辑

# 再接着保存

Syntax error, q|Q for quiting,others for editing: q  # 按 q 键,直接退出

Quit.



[root@mail scripts]# cp mkscript /bin        # 放到bin目录下,以后可以直接用了

[root@mail scripts]#



[root@mail scripts]# mkscript -d "helfsdfdsfe" ab.sh  # -d 会报错

basename:无效选项 -- d

请尝试执行“basename --help”来获取更多信息。

basename:无效选项 -- d

请尝试执行“basename --help”来获取更多信息。

Syntax error, q|Q for quiting,others for editing: q



getopts 是 bash 内置的一个命令,它能够获取一个 bash 脚本的选项,还能获取选项后面跟的参数,并且在脚本中能够调用的

只能够支持短选项,不支持长选项  选项用引号引起来

有些选项带参数      后面用冒号

有些选项不带参数       


[root@mail scripts]# type getopts

getopts is a shell builtin

[root@mail scripts]#


[root@mail scripts]# help getopts

getopts: getopts optstring name [arg]

    Getopts is used by shell procedures to parse positional parameters.


    OPTSTRING contains the option letters to be recognized; if a letter

    is followed by a colon, the option is expected to have an argument,

    which should be separated from it by white space.


    Each time it is invoked, getopts will place the next option in the

    shell variable $name, initializing name if it does not exist, and

    the index of the next argument to be processed into the shell

    variable OPTIND.  OPTIND is initialized to 1 each time the shell or

    a shell script is invoked.  When an option requires an argument,

    getopts places that argument into the shell variable OPTARG.


    getopts reports errors in one of two ways.  If the first character

    of OPTSTRING is a colon, getopts uses silent error reporting.  In

    this mode, no error messages are printed.  If an invalid option is

    seen, getopts places the option character found into OPTARG.  If a

    required argument is not found, getopts places a ':' into NAME and

    sets OPTARG to the option character found.  If getopts is not in

    silent mode, and an invalid option is seen, getopts places '?' into

    NAME and unsets OPTARG.  If a required argument is not found, a '?'

    is placed in NAME, OPTARG is unset, and a diagnostic message is

    printed.


    If the shell variable OPTERR has the value 0, getopts disables the

    printing of error messages, even if the first character of

    OPTSTRING is not a colon.  OPTERR has the value 1 by default.


    Getopts normally parses the positional parameters ($0 - $9), but if

    more arguments are given, they are parsed instead.

[root@mail scripts]#



[root@mail scripts]# mkscript opttest.sh

#!/bin/bash

# Name: opttest.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 14:24:38

# Usage: opttest.sh

getopts "bd" OPT

echo $OPT    # 得到选项 b 或 d 


[root@mail scripts]# ./opttest.sh -b

b

[root@mail scripts]# ./opttest.sh -d

d

[root@mail scripts]# ./opttest.sh -b -d  # 只取第一个

b

[root@mail scripts]# ./opttest.sh -d -b  # 只取第一个

d

[root@mail scripts]#

[root@mail scripts]# ./opttest.sh -bd

b

[root@mail scripts]#


getopts  默认情况下,只能获取一个选项

d这个选项后面 跟 :  ,表示这个选项后面有参数

$OPTARG    是  getopts   这个命令系统内置的变量

"bd:"     d后面有冒号,表示接受参数 b 后面没有冒号是不接受参数的,要想接受参数 ,必须 b:d:                 :b:d: (最前面加个冒号)表示当不存的选项 比如用 -c 时,此时就不会报错了(忽略错误)


[root@mail scripts]# mkscript opttest.sh

#!/bin/bash

# Name: opttest.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 14:24:38

# Usage: opttest.sh

getopts "bd:" OPT

echo $OPT

echo $OPTARG


[root@mail scripts]# ./opttest.sh  -d  "haha"        # d 选项后面接受参数 

d

haha

[root@mail scripts]#   


[root@mail scripts]# ./opttest.sh  -b "haha"        # b 选项后面不接受参数 

b


[root@mail scripts]# mkscript opttest.sh    # b后面有冒号,可以接受参数了

#!/bin/bash

# Name: opttest.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 14:24:38

# Usage: opttest.sh

getopts "b:d:" OPT   # b后面有冒号,可以接受参数了

echo $OPT

echo $OPTARG


[root@mail scripts]# ./opttest.sh -b "aa"   #b的参数出来了

b

aa

[root@mail scripts]# 



[root@mail scripts]# ./opttest.sh -c "aa"  # 错误的选项 就会报错

./opttest.sh: illegal option -- c

\


[root@mail scripts]#





[root@mail scripts]# mkscript opttest.sh

#!/bin/bash

# Name: opttest.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 14:24:38

# Usage: opttest.sh

getopts ":b:d:" OPT   # 在选项最前面加个冒号,此时错误的选项也不会输出错误了

echo $OPT

echo $OPTARG



[root@mail scripts]# ./opttest.sh -c   # 不存在的选项时,此时就不报错了

\

c

[root@mail scripts]#




image.png


\?   (反斜杠问号)  应该只是约等于 *  (星号)基于等于,任意的意思吧

\?  (反斜杠问号) 匹配单个字符吧  是不是 不要反斜杠,仅仅使用 ?  (问号) 也可以吧,经测试 仅仅问号是可以的


[root@mail scripts]# mkscript opttest.sh   # -b -d 后面的选项是需要参数的

#!/bin/bash

# Name: opttest.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 14:24:38

# Usage: opttest.sh

while getopts ":b:d:" SWITCH; do

 case $SWITCH in

  b) echo "The option is b.";;

  d) echo "The option is d.";;

  *) echo "Wrong option.";;

 esac


done

[root@mail scripts]# ./opttest.sh -b aaaa  

The option is b.

[root@mail scripts]#


[root@mail scripts]# ./opttest.sh -d "hello"

The option is d.

[root@mail scripts]#



[root@mail scripts]# ./opttest.sh -c

Wrong option.

[root@mail scripts]# ./opttest.sh -m

Wrong option.

[root@mail scripts]#



[root@mail scripts]# ./opttest.sh -b haha -d "hello"

The option is b.

The option is d.

[root@mail scripts]#



[root@mail scripts]# mkscript opttest.sh

#!/bin/bash

# Name: opttest.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 14:24:38

# Usage: opttest.sh

while getopts ":b:d:" SWITCH; do

 case $SWITCH in

  b) echo "The option is b."

     echo $OPTARG;;   # $OPTARG 此时表示 b 这个选项后面跟的参数

  d) echo "The option is d."

     echo $OPTARG;;  # $OPTARG 此时表示 d 这个选项后面跟的参数

  *) 

     echo "Wrong option.";;

 esac

done



[root@mail scripts]# ./opttest.sh -b haha -d "hello"

The option is b.

haha

The option is d.

hello

[root@mail scripts]#


[root@mail scripts]# mkscript opttest.sh

#!/bin/bash

# Name: opttest.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 14:24:38

# Usage: opttest.sh

USAGE() {

  echo "Usage: opttest.sh [-d argu] [-b argu]"

}

while getopts ":b:d:" SWITCH; do

 case $SWITCH in

  b) echo "The option is b."

     echo $OPTARG;;

  d) echo "The option is d."

     echo $OPTARG;;

  *) USAGE ;;  # 当有出错的选项的情况下,我们调用这个函数 USAGE

 esac

done



[root@mail scripts]# ./opttest.sh -l      # 此时就会报友好的错误信息了

Usage: opttest.sh [-d argu] [-b argu]

[root@mail scripts]#




[root@mail scripts]# vim /bin/mkscript

#!/bin/bash

# Name: mkscript

# Description: Create script

# Author: Magedu

# Datatime: 03/02/12 14:42:00

# Usage: mkscript FILENAME

while getopts ":d:" SWITCH; do

  case $SWITCH in

    d)

      DESC=$OPTARG;;

    \?)

      echo "Usage: mkscript [-d DESCRIPTION] FILENAME";;

  esac

done


shift $[$OPTIND-1]   # 每次使用一次就弹出一次,这是最后一次弹出? 

#最后 shift 之后 $1 就是文件名了      #     $[$OPTIND-1] 是下一个位置的意思


if ! grep "[^[:space:]]" $1 &> /dev/null; then

cat > $1 << EOF

#!/bin/bash

# Name: `basename $1`

# Description: $DESC

# Author: Magedu

# Version: 0.0.1

# Datetime: `date +"%F %T"`

# Usage: `basename $1`


EOF


fi


vim + $1


until bash -n $1 &> /dev/null; do

  read -p "Syntax error, q|Q for quiting,others for editing: " OPT

  case $OPT in

    q|Q)

        echo "Quit."

        exit 8;;

    *)

        vim + $1;;

  esac

done;


chmod +x $1






shift 命令

./scripts a b c d 

a就是$1

b就是$2

c就是$3

d就是$4


先取 $1 是 a ;shift 一下, $1 是 b;再shift一下,$1就是c


getopts 还有一个内置参数(变量): OPTIND  ,叫选项索引

./script -a -b -d /tmp/a

OPTIND   开始指向-a ,取走-a后,OPTIND指向了-b ...... 最后的时候OPTIND就指向了 文件名 /tmp/a 

shift $((OPTIND-1))




getopts:

    OPTIND

    OPTARG




[root@mail scripts]# vim opttest.sh

#!/bin/bash

# Name: opttest.sh

# Description:

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-02 14:24:38

# Usage: opttest.sh

USAGE() {

  echo "Usage: opttest.sh [-d argu] [-b argu]"

}

while getopts ":bd" SWITCH; do

 case $SWITCH in

  b) echo "The option is b."

     echo $OPTARG

     echo $OPTIND;;

  d) echo "The option is d."

     echo $OPTARG

     echo $OPTIND;;

  *) USAGE ;;

 esac

done



[root@mail scripts]# ./opttest.sh -b

The option is b.


2

[root@mail scripts]# ./opttest.sh -d

The option is d.


2

[root@mail scripts]#


[root@mail scripts]# ./opttest.sh -b -d

The option is b.


2

The option is d.


3

[root@mail scripts]#



[root@mail scripts]# ./opttest.sh -bd

The option is b.


1   # 这个是1没看懂  是看下一个?下一个是1,那它就是1

The option is d.


2  #下一个是2,那它就是2

[root@mail scripts]# 

$OPTIND 永远是当前正在使用的下一个


image.png



[root@mail scripts]# mkscript -d "Get ethernet information" getinterface.sh

#!/bin/bash

# Name: getinterface.sh

# Description: Get ethernet information

# Author: Magedu

# Version: 0.0.1

# Datetime: 2020-09-03 11:25:34

# Usage: getinterface.sh

SHOWIP() {       # $1是参数,这里指的是网卡名;根据网卡名 显示 ip

  if ! ifconfig | grep -o "^[^[:space:]]\{1,\}" | grep $1 &> /dev/null; then

     return 13

  fi


  echo -n "${1}:"

  ifconfig $1 | grep -o "inet addr:[0-9\.]\{1,\}" | cut -d: -f2

}


SHOWETHER() {      # $1是参数,这里指的是ip地址;根据 ip 显示 网卡名 

  if ! ifconfig | grep -o "inet addr:[0-9\.]\{1,\}" | cut -d: -f2 | grep $1 &> /dev/null; then

     return 14

  fi

  echo -n "${1}:"

  ifconfig | grep -B 1 "$1" | grep -o "^[^[:space:]]\{1,\}"

}


USAGE() {

  echo "getinterface.sh <-i interface|-I IP>"

}



while getopts ":i:I:" SWITCH; do

  case $SWITCH in

    i)

      SHOWIP $OPTARG

      [ $? -eq 13 ] && echo "Wrong ethercard."

      ;;

    I)

      SHOWETHER $OPTARG

      [ $? -eq 14 ] && echo "Wrong IP."

      ;;

    \?)   # 井号 问号 任意单个字符

      USAGE

  esac

done



[root@mail scripts]# ./getinterface.sh -i eth0

eth0:192.168.1.75

[root@mail scripts]# ./getinterface.sh -i eth1

Wrong ethercard.

[root@mail scripts]#

[root@mail scripts]# ./getinterface.sh -I 192.168.1.75

192.168.1.75:eth0

[root@mail scripts]#


[root@mail scripts]# ./getinterface.sh -I 192.168.1.76

Wrong IP.

[root@mail scripts]#


[root@mail scripts]# ./getinterface.sh -I 192.168.1.75 -i eth0  # 两个一块用

192.168.1.75:eth0

eth0:192.168.1.75

[root@mail scripts]#





普通分类: