SlideShare a Scribd company logo
1 of 33
Download to read offline
BASH编程之变量高级篇

使用实例来讲解更多的bash符号的使用方法
 注:本PPT中的部分代码转载,部分原创




       指导老师:杨坤 QQ: 12238747
     蓝狐教育系统培训中心 0731-84125710
内部变量
• $$ 与 $BASHPID 都代表着执行程序的进程ID,我们可以通过
 echo打印,并用 ps 指令检查得到相同的进程ID

  –echo $$

  –echo $BASHPID

  –ps ax | grep bash
  –11015 pts/2           R       0:00 /bin/bash




                   指导老师:杨坤 QQ: 12238747
                 蓝狐教育系统培训中心 0731-84125710
位置参数(一)
• 我们经常向一个程序传递以空格间隔的参数,我们按先后次序
    分成 $0 (脚本本身), $1(参数1) , $2(参数2) .....

• $# 表示参数数量的总数,也就是总共有多少参数
• $* 所有的参数以一行显示
• $@ 所有的参数以空格分隔
•   E_BADARGS=65
•   if [   !   -n "$1" ]
•   then
     – echo "Usage:    `basename $0`   arg1 arg2 ..." # 提示脚本使用方法
     – exit $E_BADARGS     # 退出返回自定义错误代码
     fi
                             指导老师:杨坤 QQ: 12238747
                           蓝狐教育系统培训中心 0731-84125710
位置参数(二)
•   index=1

•   for arg in "$*"       # 使用 $* ,也就是所有参数做一行处理

    替换成 for arg in "$@" 再运行一次本程序             # 使用 $@ ,将会将参数以空格
    分隔一一处理

•   do

         echo "Arg   #$index = $arg"

         let "index+=1"   # index 递增 1,注意这时对变量的调用不用在变量前加 $
    done

• let 可以对 C 语言的表达式做计算,还有另外一种方法实
    现 $((index+=1))

                            指导老师:杨坤 QQ: 12238747
                          蓝狐教育系统培训中心 0731-84125710
强制退出程序本身示例(一)
• $! 代表进程本身
• vi &       #此处运行了一个vi编辑工具以便测试

•   { sleep ${TIMEOUT};    #休眠一定时间

• eval 'kill -9 $!' &> /dev/null ; } # 杀死进程本身


• eval 可以对字符串的代码当成bash代码并运行,等同于
• `` 和 $( )


                     指导老师:杨坤 QQ: 12238747
                   蓝狐教育系统培训中心 0731-84125710
强制退出程序本身示例(二)
TIMEOUT=30    # 超时时间
count=0 # 初始值
vi & {
    while ((count < TIMEOUT )); do
         eval '[ ! -d "/proc/$!" ] && ((count = TIMEOUT))'
         ((count++)) # 计数器递增
         sleep 1
    done
  eval '[ -d "/proc/$!" ] && kill -15 $!'   # 判断程序运行后
   是否在 /proc下存在以进程ID的目录夹,如果存在杀死该进程
}

• (( ))中变量无需在变量前使用 $ ,而且没有空格的局限性


                     指导老师:杨坤 QQ: 12238747
                   蓝狐教育系统培训中心 0731-84125710
字符长度
• 这三种方法都可以取出字符串的长度
    ${#string}
    expr length $string

    expr "$string" : '.*'


•   stringZ=abcABC123ABCabc

•   echo ${#stringZ}                  # 得到 15

•   echo `expr length $stringZ`       # 得到 15

•   echo `expr "$stringZ" : '.*'`     # 得到 15

•                           ^^        #空格
                         指导老师:杨坤 QQ: 12238747
                       蓝狐教育系统培训中心 0731-84125710
表达式方式取长度
• 依据正则表达式取得相匹配部分的长度,注意表达式要用单引
    号

• expr match "$string" '$substring'
• expr "$string" : '$substring'
•   stringZ=abcABC123ABCabc

•   #       |------|

•   #       12345678

•   echo `expr match "$stringZ" 'abc[A-Z]*.2'`    # 得到 8

•   echo `expr "$stringZ" : 'abc[A-Z]*.2'`        # 得到 8



                         指导老师:杨坤 QQ: 12238747
                       蓝狐教育系统培训中心 0731-84125710
子字符串的提取(符号)
• 根据字符的位置提取字符串中一段,注意此方法索引由0开始
• ${string:position}
• ${string:position:length}
•   stringZ=abcABC123ABCabc
•   #       0123456789.....

•   echo ${stringZ:0}      # 没有给定长度,又从0(第一个字符)开始,将取所有的
    字符 得到 abcABC123ABCabc
•   echo ${stringZ:1}      # 从1(第二个字符)开始 得到 bcABC123ABCabc
•   echo ${stringZ:7}      # 从7(第八个字符)开始 得到 23ABCabc
•   echo ${stringZ:7:3}    # 从第八个字符开始,取三个字符 得到 23A



                            指导老师:杨坤 QQ: 12238747
                          蓝狐教育系统培训中心 0731-84125710
子字符串的提取(函数)
• 也可以使用 substr 函数提取,注意这个函数索引从1开始
• expr substr $string $position $length


•   stringZ=abcABC123ABCabc

•   #       123456789......

•   echo `expr substr $stringZ 1 2`               # 得到 ab

•   echo `expr substr $stringZ 4 3`               # 得到 ABC




                         指导老师:杨坤 QQ: 12238747
                       蓝狐教育系统培训中心 0731-84125710
表达式方式前面提取字符串
• 按照正则表达式从前面开始提取字符串,注意表达式写在 ( )
• expr match "$string" '($substring)'
• expr "$string" : '($substring)'


•   stringZ=abcABC123ABCabc
•   #       =======
•   echo `expr match "$stringZ" '(.[b-c]*[A-Z]..[0-9])'`   #
    abcABC1
•   echo `expr "$stringZ" : '(.[b-c]*[A-Z]..[0-9])'`       #
    abcABC1
•   echo `expr "$stringZ" : '(.......)'`                   #
    abcABC1


                         指导老师:杨坤 QQ: 12238747
                       蓝狐教育系统培训中心 0731-84125710
表达式方式后面提取字符串
• 按照正则表达式从后面开始提取字符串,注意表达式写在 ( )
• .* 中“.”表示任何字符,“*”表示0到无穷的匹配
• expr match "$string" '.*($substring)'
• expr "$string" : '.*($substring)


•   stringZ=abcABC123ABCabc
•   #                ======
•   echo `expr match "$stringZ" '.*([A-C][A-C][A-C][a-c]*)'`     #
    ABCabc

•   echo `expr "$stringZ" : '.*(......)'`          # 得到 ABCabc

                          指导老师:杨坤 QQ: 12238747
                        蓝狐教育系统培训中心 0731-84125710
表达式方式前面字符串移除
• 按照正则表达式从前面开始移除字符串中的部分
• ${string#substring}             仅移除最先匹配的部分

• ${string##substring}            只要是匹配统统移除
•   stringZ=abcABC123ABCabc
    #       |----|             开始部分匹配

•   #       |----------|       移除所有匹配

•   echo ${stringZ#a*C}         # 移除从a到大写C最开始匹配的部分,最后得到
    123ABCabc

•   echo ${stringZ##a*C}        # 从a到大写C所有可能, 最后得到 abc




                            指导老师:杨坤 QQ: 12238747
                          蓝狐教育系统培训中心 0731-84125710
表达式方式后面字符串移除
• 按照正则表达式从后面开始移除字符串中的部分
• ${string%substring}              仅移除从后面开始最先匹配的部分

• ${string%%substring}             只要是匹配统统移除
•   # 重命名所有在 $PWD 下的带 "TXT" 后缀的文件,将其变成 "txt" 后缀 比如 "file1.TXT"
    将变成 "file1.txt" . . .,这个可以很好的解决windows文件拷入到Linux中的问题
•   SUFF=TXT
•   suff=txt
•   for i in $(ls *.$SUFF)
•   do
•        mv -vf $i ${i%.$SUFF}.$suff                  # 移除后缀加新后缀
•   done

                             指导老师:杨坤 QQ: 12238747
                           蓝狐教育系统培训中心 0731-84125710
表达式方式字符串替换
• 有点雷同与 sed 的表达式
• ${string/substring/replacement} 首先匹配的被替换
• ${string//substring/replacement} 匹配的全部替换
•   stringZ=abcABC123ABCabc
    match=abc

•   repl=000

•   echo ${stringZ/$match/$repl}       # 000ABC123ABCabc

•   #              ^          ^          ^^^

•   echo ${stringZ//$match/$repl} # 000ABC123ABC000

•   # Yes!             ^          ^      ^^^          ^^^

                             指导老师:杨坤 QQ: 12238747
                           蓝狐教育系统培训中心 0731-84125710
表达式方式字符串替换
• 从前面很多的例子中我们可以看到在 ${} 中“#”代表从前
    面,“%”代表从后面,因此

• ${string/#substring/replacement} 从前面查找并替换
• ${string/%substring/replacement} 从后面查找并替换


•   stringZ=abcABC123ABCabc

•   echo ${stringZ/#abc/XYZ}           # XYZABC123ABCabc

•                                      # 从前面将 'abc' 替换成 'XYZ'.

•   echo ${stringZ/%abc/XYZ}           # abcABC123ABCXYZ

•                                      # 从后面将 'abc' 替换成 'XYZ'.
                         指导老师:杨坤 QQ: 12238747
                       蓝狐教育系统培训中心 0731-84125710
参数替换(一)
• ${parameter} 与直接使用 $parameter 相同,但在很多的情
    况下使用${}可以减少歧义。


•   your_id=${USER}-on-${HOSTNAME}

•   echo "$your_id"

•   #

•   echo "Old $PATH = $PATH"

•   PATH=${PATH}:/opt/bin   #添加/opt/bin到PATH变量中

•   echo "New $PATH = $PATH"




                         指导老师:杨坤 QQ: 12238747
                       蓝狐教育系统培训中心 0731-84125710
参数替换(二)
• ${parameter-default}, ${parameter:-default}
• 如果参数没有设置,将使用默认值
•   username0=

•   # username0 已经声明了,但为空

•   echo "username0 = ${username0-`whoami`}"

•   # echo 没有显示

•   # 之前没有定义过 username1

•   echo "username1 = ${username1-`whoami`}"

•   # 此时将显示当前用户名




                         指导老师:杨坤 QQ: 12238747
                       蓝狐教育系统培训中心 0731-84125710
参数替换(二)实例分析
• DEFAULT_FILENAME=generic.data
• filename=${1:-$DEFAULT_FILENAME}


• 等同于下面的一段代码
•   if [ ! -n $1 ]     # 如果位置第一个位置参数长度为0(没有设置$1)

•   then           # 那么

•          filename=gerneric.data    # filename设置为缺省的值

•   fi




                            指导老师:杨坤 QQ: 12238747
                          蓝狐教育系统培训中心 0731-84125710
参数替换(三)
• 下面的表达式与之前的表达式雷同,细微的不同的
    ${parameter-default}只判断参数是否已经设置

• ${parameter=default}, ${parameter:=default}
• 如果参数已经设置,但为空,将使用缺省值
•   echo ${username=`whoami`}

•   此处,之前没有定义过username,那么变量将设置为`whoami`命令的结果
•   if [ -n $username ]; then
     – username=$username
•   else
     – username=`whoami`

•   fi
                              指导老师:杨坤 QQ: 12238747
                            蓝狐教育系统培训中心 0731-84125710
参数替换(四)
• 如果参数设置了,使用替换值,否则清空变量
• ${parameter+alt}, ${parameter:+alt}
• 逻辑等同于
    if [   -n $parameter      ]

    then

         parameter=$alt

    else

         parameter=               # 清空此参数

•   fi



                            指导老师:杨坤 QQ: 12238747
                          蓝狐教育系统培训中心 0731-84125710
参数替换(四)实例分析
• 如果参数设置了,使用替换值,否则清空变量
• ${parameter+alt}, ${parameter:+alt}
•   a=${param1+xyz}   # 由于param1没有设置所以a为空

•   echo "a = $a"      # a =

•   param2=            # param2设置为空

•   a=${param2+xyz}

•   echo "a = $a"      # 有设置将替换成缺省值 a = xyz

•   param3=123         # param3设置为123

•   a=${param3+xyz}

    echo "a = $a"       # 有设置将替换成缺省值 a = xyz


                         指导老师:杨坤 QQ: 12238747
                       蓝狐教育系统培训中心 0731-84125710
错误检测
• 判断参数是否设置,没有将打印后面的错误信息,
• ${parameter?error_msg}, ${parameter:?error_msg}


• 下面的例子可以直接对系统变量检查,如果没有设置,将直接
    退出程序
    ${HOSTNAME?} ${USER?}   ${HOME?}   ${MAILBOX?}

•   : ${ZZXy23AB?"ZZXy23AB has not been set"}

•   ${1?"Usage: $0 x.x.x.x"}   # 最为简单的方式检查是否设置位置1参数




                         指导老师:杨坤 QQ: 12238747
                       蓝狐教育系统培训中心 0731-84125710
综合实例一
• echo `basename $PWD`          # 打印当前工作路径最后一段子目录名字
• echo "${PWD##*/}"             # 另一种方法的实现
• echo
• echo `basename $0`            # 得到脚本的名字
• echo $0                       # 另一种方法的实现
• echo "${0##*/}"               # 另一种方法的实现
• echo
• filename=test.data
• echo "${filename##*.}"        # 移除"."之前的内容,得到 data 文
  件名的后缀

                        指导老师:杨坤 QQ: 12238747
                      蓝狐教育系统培训中心 0731-84125710
综合实例二
• 下面的例子实现将特定的文件名后缀,比如 .gif 统统改
    为其他后缀
•   for filename in *.$1

•   # 遍历当前整个目录中所有指定的文件后缀

•   do

•        mv $filename ${filename%$1}$2

•        #   去除掉输入的文件名后缀再追加另外指定的一个

•   done

•   exit 0




                            指导老师:杨坤 QQ: 12238747
                          蓝狐教育系统培训中心 0731-84125710
综合实例三
•   path_name=/home/bozo/ideas/thoughts.for.today

•   echo "path_name = $path_name"

•   t=${path_name##/*/}           # 根据表达式最大可能的移除/部分,最后只留
    下文件名

•   echo "path_name, stripped of prefixes = $t"

•   t=${path_name%/} ; t=${t##*/};      # 同样的效果

• 下面的例子将一个用户 yangwawa主目录的文件拷贝到
    另一个用户 joe(可以用$1代替写在脚本中)的主目录中
•   FILENAME=/home/yangwawa/.bash_profile

•   cp -v $FILENAME{,${FILENAME/yangwawa/joe}}


                            指导老师:杨坤 QQ: 12238747
                          蓝狐教育系统培训中心 0731-84125710
定义一个变量
• declare -r 定义一个只读变量
• declare -i 定义的变量是一个数字,对于数字变量可以不用在
 变量名前使用"$"符号

• declare -a 定义的是数组
• declare -f 定义的是函数
• declare -x 定义的变量在bash中等同于 export 可以为其他
 程序所用



                 指导老师:杨坤 QQ: 12238747
               蓝狐教育系统培训中心 0731-84125710
declare显示变量
• declare 命令对于标识变量也非常有用
•   bash$ declare | grep HOME
•   /home/bozo

•   bash$ zzy=68
•   bash$ declare | grep zzy
•   zzy=68

•   bash$ Colors=([0]="purple" [1]="reddish-orange" [2]="light green")
•   bash$ echo ${Colors[@]}
•   purple reddish-orange light green

•   bash$ declare | grep Colors
•   Colors=([0]="purple" [1]="reddish-orange" [2]="light green")



                                 指导老师:杨坤 QQ: 12238747
                               蓝狐教育系统培训中心 0731-84125710
数组概述
• 申明数组
   declare -a array

   array[xx]

• 调用时
   ${array[xx]}




                    指导老师:杨坤 QQ: 12238747
                  蓝狐教育系统培训中心 0731-84125710
数组使用实例一
BOOKS[0]=”RHEL5.0”
BOOKS[1]=”Windows 7”
BOOKS[2]=”Unix”
for IDX in 0 1 2
do
     printf “ %sn” “${BOOKS[IDX]}”
done




                       指导老师:杨坤 QQ: 12238747
                     蓝狐教育系统培训中心 0731-84125710
• arrayZ=( one two three four five )
• echo ${arrayZ[@]:0}      #one two three four five

• echo ${arrayZ[@]:1}      #two three four five

• echo ${arrayZ[@]:1:2}    #two three




                     指导老师:杨坤 QQ: 12238747
                   蓝狐教育系统培训中心 0731-84125710
综合使用实例
• 在数组中查找所有的元素,找到想匹配的并将其移除(此处是
 最短匹配)

 echo ${arrayZ[@]#t*e} #one two e four five

• 同上(此处是最长匹配)
 echo ${arrayZ[@]##t*e} #one two four five




                  指导老师:杨坤 QQ: 12238747
                蓝狐教育系统培训中心 0731-84125710
•




            谢谢!
       任何问题请 email:
    yangwawa0323@163.com

           指导老师:杨坤 QQ: 12238747
         蓝狐教育系统培训中心 0731-84125710

More Related Content

What's hot

Patterns in Zend Framework
Patterns in Zend FrameworkPatterns in Zend Framework
Patterns in Zend FrameworkJace Ju
 
Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18Derek Lee
 
Python入門:5大概念初心者必備
Python入門:5大概念初心者必備Python入門:5大概念初心者必備
Python入門:5大概念初心者必備Derek Lee
 
6, awk
6, awk6, awk
6, awkted-xu
 
advanced introduction to codeigniter
advanced introduction to codeigniteradvanced introduction to codeigniter
advanced introduction to codeigniterBo-Yi Wu
 
Perl 6 news at 2010-06
Perl 6 news at 2010-06Perl 6 news at 2010-06
Perl 6 news at 2010-06March Liu
 
jQuery源码学习
jQuery源码学习jQuery源码学习
jQuery源码学习fangdeng
 
Testing in python 2.7.3
Testing in python 2.7.3Testing in python 2.7.3
Testing in python 2.7.3Wen Liao
 
深入了解Memcache
深入了解Memcache深入了解Memcache
深入了解Memcachezubin Jiang
 
OpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part IOpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part IHung-yu Lin
 
LazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHPLazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHPLin Yo-An
 

What's hot (17)

Patterns in Zend Framework
Patterns in Zend FrameworkPatterns in Zend Framework
Patterns in Zend Framework
 
Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18Python入門:5大概念初心者必備 2021/11/18
Python入門:5大概念初心者必備 2021/11/18
 
Python 温故
Python 温故Python 温故
Python 温故
 
Python入門:5大概念初心者必備
Python入門:5大概念初心者必備Python入門:5大概念初心者必備
Python入門:5大概念初心者必備
 
6, awk
6, awk6, awk
6, awk
 
advanced introduction to codeigniter
advanced introduction to codeigniteradvanced introduction to codeigniter
advanced introduction to codeigniter
 
PHP
PHPPHP
PHP
 
Perl 6 news at 2010-06
Perl 6 news at 2010-06Perl 6 news at 2010-06
Perl 6 news at 2010-06
 
Ch8
Ch8Ch8
Ch8
 
jQuery源码学习
jQuery源码学习jQuery源码学习
jQuery源码学习
 
Python串列資料應用
Python串列資料應用Python串列資料應用
Python串列資料應用
 
Testing in python 2.7.3
Testing in python 2.7.3Testing in python 2.7.3
Testing in python 2.7.3
 
深入了解Memcache
深入了解Memcache深入了解Memcache
深入了解Memcache
 
OpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part IOpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part I
 
LazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHPLazyRecord: The Fast ORM for PHP
LazyRecord: The Fast ORM for PHP
 
Python元組,字典,集合
Python元組,字典,集合Python元組,字典,集合
Python元組,字典,集合
 
Swift基礎
Swift基礎Swift基礎
Swift基礎
 

Viewers also liked

Death To Paper Drupal Fresno
Death To Paper Drupal FresnoDeath To Paper Drupal Fresno
Death To Paper Drupal FresnoBob Kepford
 
De la biblioteca tradicional a la biblioteca 2.0”: el uso de herramientas soc...
De la biblioteca tradicional a la biblioteca 2.0”: el uso de herramientas soc...De la biblioteca tradicional a la biblioteca 2.0”: el uso de herramientas soc...
De la biblioteca tradicional a la biblioteca 2.0”: el uso de herramientas soc...Lorena Lopez
 
Fpe core presentation 05 28 2013 (1)
Fpe core presentation 05 28 2013 (1)Fpe core presentation 05 28 2013 (1)
Fpe core presentation 05 28 2013 (1)familypromiseec
 
Design de Interação - Parte 2
Design de Interação - Parte 2Design de Interação - Parte 2
Design de Interação - Parte 2Flavia Siqueira
 

Viewers also liked (7)

Death To Paper Drupal Fresno
Death To Paper Drupal FresnoDeath To Paper Drupal Fresno
Death To Paper Drupal Fresno
 
De la biblioteca tradicional a la biblioteca 2.0”: el uso de herramientas soc...
De la biblioteca tradicional a la biblioteca 2.0”: el uso de herramientas soc...De la biblioteca tradicional a la biblioteca 2.0”: el uso de herramientas soc...
De la biblioteca tradicional a la biblioteca 2.0”: el uso de herramientas soc...
 
Fpe core presentation 05 28 2013 (1)
Fpe core presentation 05 28 2013 (1)Fpe core presentation 05 28 2013 (1)
Fpe core presentation 05 28 2013 (1)
 
Familia Actual Cris Isa
Familia Actual Cris  IsaFamilia Actual Cris  Isa
Familia Actual Cris Isa
 
dominios y alojamientos web
dominios y alojamientos webdominios y alojamientos web
dominios y alojamientos web
 
S Ta R Chart
S Ta R ChartS Ta R Chart
S Ta R Chart
 
Design de Interação - Parte 2
Design de Interação - Parte 2Design de Interação - Parte 2
Design de Interação - Parte 2
 

Similar to Bash编程之变量高级篇

2, bash synax simplified
2, bash synax simplified2, bash synax simplified
2, bash synax simplifiedted-xu
 
Ruby程式語言入門導覽
Ruby程式語言入門導覽Ruby程式語言入門導覽
Ruby程式語言入門導覽Mu-Fan Teng
 
Swift Functional Programming
Swift Functional ProgrammingSwift Functional Programming
Swift Functional Programming林藍 東
 
實踐大學教案20140329
實踐大學教案20140329實踐大學教案20140329
實踐大學教案20140329Mu-Fan Teng
 
Maintainable PHP Source Code
Maintainable PHP Source CodeMaintainable PHP Source Code
Maintainable PHP Source CodeBo-Yi Wu
 
Python 入門
Python 入門 Python 入門
Python 入門 Andy Yao
 
Neo4j in depth session1
Neo4j in depth session1Neo4j in depth session1
Neo4j in depth session1Samchu Li
 
Android混淆技巧与反混淆 小波
Android混淆技巧与反混淆 小波Android混淆技巧与反混淆 小波
Android混淆技巧与反混淆 小波正炎 高
 
Free Marker中文文档
Free Marker中文文档Free Marker中文文档
Free Marker中文文档yiditushe
 
Shell脚本
Shell脚本Shell脚本
Shell脚本bj
 
20161209-Julia Taiwan first meetup-julia語言入門
20161209-Julia Taiwan first meetup-julia語言入門20161209-Julia Taiwan first meetup-julia語言入門
20161209-Julia Taiwan first meetup-julia語言入門岳華 杜
 

Similar to Bash编程之变量高级篇 (20)

2, bash synax simplified
2, bash synax simplified2, bash synax simplified
2, bash synax simplified
 
Ruby程式語言入門導覽
Ruby程式語言入門導覽Ruby程式語言入門導覽
Ruby程式語言入門導覽
 
Swift Functional Programming
Swift Functional ProgrammingSwift Functional Programming
Swift Functional Programming
 
實踐大學教案20140329
實踐大學教案20140329實踐大學教案20140329
實踐大學教案20140329
 
Ch4 教學
Ch4 教學Ch4 教學
Ch4 教學
 
Ch4
Ch4Ch4
Ch4
 
Maintainable PHP Source Code
Maintainable PHP Source CodeMaintainable PHP Source Code
Maintainable PHP Source Code
 
Python 入門
Python 入門 Python 入門
Python 入門
 
Neo4j in depth session1
Neo4j in depth session1Neo4j in depth session1
Neo4j in depth session1
 
Android混淆技巧与反混淆 小波
Android混淆技巧与反混淆 小波Android混淆技巧与反混淆 小波
Android混淆技巧与反混淆 小波
 
Vim雕虫小技
Vim雕虫小技Vim雕虫小技
Vim雕虫小技
 
Ch6 教學
Ch6 教學Ch6 教學
Ch6 教學
 
Ch6
Ch6Ch6
Ch6
 
Ch8 教學
Ch8 教學Ch8 教學
Ch8 教學
 
Free Marker中文文档
Free Marker中文文档Free Marker中文文档
Free Marker中文文档
 
Ch9
Ch9Ch9
Ch9
 
R intro 20140716-basic
R intro 20140716-basicR intro 20140716-basic
R intro 20140716-basic
 
Shell脚本
Shell脚本Shell脚本
Shell脚本
 
Ch10 習題
Ch10 習題Ch10 習題
Ch10 習題
 
20161209-Julia Taiwan first meetup-julia語言入門
20161209-Julia Taiwan first meetup-julia語言入門20161209-Julia Taiwan first meetup-julia語言入門
20161209-Julia Taiwan first meetup-julia語言入門
 

Bash编程之变量高级篇

  • 2. 内部变量 • $$ 与 $BASHPID 都代表着执行程序的进程ID,我们可以通过 echo打印,并用 ps 指令检查得到相同的进程ID –echo $$ –echo $BASHPID –ps ax | grep bash –11015 pts/2 R 0:00 /bin/bash 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 3. 位置参数(一) • 我们经常向一个程序传递以空格间隔的参数,我们按先后次序 分成 $0 (脚本本身), $1(参数1) , $2(参数2) ..... • $# 表示参数数量的总数,也就是总共有多少参数 • $* 所有的参数以一行显示 • $@ 所有的参数以空格分隔 • E_BADARGS=65 • if [ ! -n "$1" ] • then – echo "Usage: `basename $0` arg1 arg2 ..." # 提示脚本使用方法 – exit $E_BADARGS # 退出返回自定义错误代码 fi 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 4. 位置参数(二) • index=1 • for arg in "$*" # 使用 $* ,也就是所有参数做一行处理 替换成 for arg in "$@" 再运行一次本程序 # 使用 $@ ,将会将参数以空格 分隔一一处理 • do echo "Arg #$index = $arg" let "index+=1" # index 递增 1,注意这时对变量的调用不用在变量前加 $ done • let 可以对 C 语言的表达式做计算,还有另外一种方法实 现 $((index+=1)) 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 5. 强制退出程序本身示例(一) • $! 代表进程本身 • vi & #此处运行了一个vi编辑工具以便测试 • { sleep ${TIMEOUT}; #休眠一定时间 • eval 'kill -9 $!' &> /dev/null ; } # 杀死进程本身 • eval 可以对字符串的代码当成bash代码并运行,等同于 • `` 和 $( ) 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 6. 强制退出程序本身示例(二) TIMEOUT=30 # 超时时间 count=0 # 初始值 vi & { while ((count < TIMEOUT )); do eval '[ ! -d "/proc/$!" ] && ((count = TIMEOUT))' ((count++)) # 计数器递增 sleep 1 done eval '[ -d "/proc/$!" ] && kill -15 $!' # 判断程序运行后 是否在 /proc下存在以进程ID的目录夹,如果存在杀死该进程 } • (( ))中变量无需在变量前使用 $ ,而且没有空格的局限性 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 7. 字符长度 • 这三种方法都可以取出字符串的长度 ${#string} expr length $string expr "$string" : '.*' • stringZ=abcABC123ABCabc • echo ${#stringZ} # 得到 15 • echo `expr length $stringZ` # 得到 15 • echo `expr "$stringZ" : '.*'` # 得到 15 • ^^ #空格 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 8. 表达式方式取长度 • 依据正则表达式取得相匹配部分的长度,注意表达式要用单引 号 • expr match "$string" '$substring' • expr "$string" : '$substring' • stringZ=abcABC123ABCabc • # |------| • # 12345678 • echo `expr match "$stringZ" 'abc[A-Z]*.2'` # 得到 8 • echo `expr "$stringZ" : 'abc[A-Z]*.2'` # 得到 8 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 9. 子字符串的提取(符号) • 根据字符的位置提取字符串中一段,注意此方法索引由0开始 • ${string:position} • ${string:position:length} • stringZ=abcABC123ABCabc • # 0123456789..... • echo ${stringZ:0} # 没有给定长度,又从0(第一个字符)开始,将取所有的 字符 得到 abcABC123ABCabc • echo ${stringZ:1} # 从1(第二个字符)开始 得到 bcABC123ABCabc • echo ${stringZ:7} # 从7(第八个字符)开始 得到 23ABCabc • echo ${stringZ:7:3} # 从第八个字符开始,取三个字符 得到 23A 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 10. 子字符串的提取(函数) • 也可以使用 substr 函数提取,注意这个函数索引从1开始 • expr substr $string $position $length • stringZ=abcABC123ABCabc • # 123456789...... • echo `expr substr $stringZ 1 2` # 得到 ab • echo `expr substr $stringZ 4 3` # 得到 ABC 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 11. 表达式方式前面提取字符串 • 按照正则表达式从前面开始提取字符串,注意表达式写在 ( ) • expr match "$string" '($substring)' • expr "$string" : '($substring)' • stringZ=abcABC123ABCabc • # ======= • echo `expr match "$stringZ" '(.[b-c]*[A-Z]..[0-9])'` # abcABC1 • echo `expr "$stringZ" : '(.[b-c]*[A-Z]..[0-9])'` # abcABC1 • echo `expr "$stringZ" : '(.......)'` # abcABC1 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 12. 表达式方式后面提取字符串 • 按照正则表达式从后面开始提取字符串,注意表达式写在 ( ) • .* 中“.”表示任何字符,“*”表示0到无穷的匹配 • expr match "$string" '.*($substring)' • expr "$string" : '.*($substring) • stringZ=abcABC123ABCabc • # ====== • echo `expr match "$stringZ" '.*([A-C][A-C][A-C][a-c]*)'` # ABCabc • echo `expr "$stringZ" : '.*(......)'` # 得到 ABCabc 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 13. 表达式方式前面字符串移除 • 按照正则表达式从前面开始移除字符串中的部分 • ${string#substring} 仅移除最先匹配的部分 • ${string##substring} 只要是匹配统统移除 • stringZ=abcABC123ABCabc # |----| 开始部分匹配 • # |----------| 移除所有匹配 • echo ${stringZ#a*C} # 移除从a到大写C最开始匹配的部分,最后得到 123ABCabc • echo ${stringZ##a*C} # 从a到大写C所有可能, 最后得到 abc 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 14. 表达式方式后面字符串移除 • 按照正则表达式从后面开始移除字符串中的部分 • ${string%substring} 仅移除从后面开始最先匹配的部分 • ${string%%substring} 只要是匹配统统移除 • # 重命名所有在 $PWD 下的带 "TXT" 后缀的文件,将其变成 "txt" 后缀 比如 "file1.TXT" 将变成 "file1.txt" . . .,这个可以很好的解决windows文件拷入到Linux中的问题 • SUFF=TXT • suff=txt • for i in $(ls *.$SUFF) • do • mv -vf $i ${i%.$SUFF}.$suff # 移除后缀加新后缀 • done 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 15. 表达式方式字符串替换 • 有点雷同与 sed 的表达式 • ${string/substring/replacement} 首先匹配的被替换 • ${string//substring/replacement} 匹配的全部替换 • stringZ=abcABC123ABCabc match=abc • repl=000 • echo ${stringZ/$match/$repl} # 000ABC123ABCabc • # ^ ^ ^^^ • echo ${stringZ//$match/$repl} # 000ABC123ABC000 • # Yes! ^ ^ ^^^ ^^^ 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 16. 表达式方式字符串替换 • 从前面很多的例子中我们可以看到在 ${} 中“#”代表从前 面,“%”代表从后面,因此 • ${string/#substring/replacement} 从前面查找并替换 • ${string/%substring/replacement} 从后面查找并替换 • stringZ=abcABC123ABCabc • echo ${stringZ/#abc/XYZ} # XYZABC123ABCabc • # 从前面将 'abc' 替换成 'XYZ'. • echo ${stringZ/%abc/XYZ} # abcABC123ABCXYZ • # 从后面将 'abc' 替换成 'XYZ'. 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 17. 参数替换(一) • ${parameter} 与直接使用 $parameter 相同,但在很多的情 况下使用${}可以减少歧义。 • your_id=${USER}-on-${HOSTNAME} • echo "$your_id" • # • echo "Old $PATH = $PATH" • PATH=${PATH}:/opt/bin #添加/opt/bin到PATH变量中 • echo "New $PATH = $PATH" 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 18. 参数替换(二) • ${parameter-default}, ${parameter:-default} • 如果参数没有设置,将使用默认值 • username0= • # username0 已经声明了,但为空 • echo "username0 = ${username0-`whoami`}" • # echo 没有显示 • # 之前没有定义过 username1 • echo "username1 = ${username1-`whoami`}" • # 此时将显示当前用户名 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 19. 参数替换(二)实例分析 • DEFAULT_FILENAME=generic.data • filename=${1:-$DEFAULT_FILENAME} • 等同于下面的一段代码 • if [ ! -n $1 ] # 如果位置第一个位置参数长度为0(没有设置$1) • then # 那么 • filename=gerneric.data # filename设置为缺省的值 • fi 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 20. 参数替换(三) • 下面的表达式与之前的表达式雷同,细微的不同的 ${parameter-default}只判断参数是否已经设置 • ${parameter=default}, ${parameter:=default} • 如果参数已经设置,但为空,将使用缺省值 • echo ${username=`whoami`} • 此处,之前没有定义过username,那么变量将设置为`whoami`命令的结果 • if [ -n $username ]; then – username=$username • else – username=`whoami` • fi 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 21. 参数替换(四) • 如果参数设置了,使用替换值,否则清空变量 • ${parameter+alt}, ${parameter:+alt} • 逻辑等同于 if [ -n $parameter ] then parameter=$alt else parameter= # 清空此参数 • fi 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 22. 参数替换(四)实例分析 • 如果参数设置了,使用替换值,否则清空变量 • ${parameter+alt}, ${parameter:+alt} • a=${param1+xyz} # 由于param1没有设置所以a为空 • echo "a = $a" # a = • param2= # param2设置为空 • a=${param2+xyz} • echo "a = $a" # 有设置将替换成缺省值 a = xyz • param3=123 # param3设置为123 • a=${param3+xyz} echo "a = $a" # 有设置将替换成缺省值 a = xyz 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 23. 错误检测 • 判断参数是否设置,没有将打印后面的错误信息, • ${parameter?error_msg}, ${parameter:?error_msg} • 下面的例子可以直接对系统变量检查,如果没有设置,将直接 退出程序 ${HOSTNAME?} ${USER?} ${HOME?} ${MAILBOX?} • : ${ZZXy23AB?"ZZXy23AB has not been set"} • ${1?"Usage: $0 x.x.x.x"} # 最为简单的方式检查是否设置位置1参数 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 24. 综合实例一 • echo `basename $PWD` # 打印当前工作路径最后一段子目录名字 • echo "${PWD##*/}" # 另一种方法的实现 • echo • echo `basename $0` # 得到脚本的名字 • echo $0 # 另一种方法的实现 • echo "${0##*/}" # 另一种方法的实现 • echo • filename=test.data • echo "${filename##*.}" # 移除"."之前的内容,得到 data 文 件名的后缀 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 25. 综合实例二 • 下面的例子实现将特定的文件名后缀,比如 .gif 统统改 为其他后缀 • for filename in *.$1 • # 遍历当前整个目录中所有指定的文件后缀 • do • mv $filename ${filename%$1}$2 • # 去除掉输入的文件名后缀再追加另外指定的一个 • done • exit 0 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 26. 综合实例三 • path_name=/home/bozo/ideas/thoughts.for.today • echo "path_name = $path_name" • t=${path_name##/*/} # 根据表达式最大可能的移除/部分,最后只留 下文件名 • echo "path_name, stripped of prefixes = $t" • t=${path_name%/} ; t=${t##*/}; # 同样的效果 • 下面的例子将一个用户 yangwawa主目录的文件拷贝到 另一个用户 joe(可以用$1代替写在脚本中)的主目录中 • FILENAME=/home/yangwawa/.bash_profile • cp -v $FILENAME{,${FILENAME/yangwawa/joe}} 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 27. 定义一个变量 • declare -r 定义一个只读变量 • declare -i 定义的变量是一个数字,对于数字变量可以不用在 变量名前使用"$"符号 • declare -a 定义的是数组 • declare -f 定义的是函数 • declare -x 定义的变量在bash中等同于 export 可以为其他 程序所用 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 28. declare显示变量 • declare 命令对于标识变量也非常有用 • bash$ declare | grep HOME • /home/bozo • bash$ zzy=68 • bash$ declare | grep zzy • zzy=68 • bash$ Colors=([0]="purple" [1]="reddish-orange" [2]="light green") • bash$ echo ${Colors[@]} • purple reddish-orange light green • bash$ declare | grep Colors • Colors=([0]="purple" [1]="reddish-orange" [2]="light green") 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 29. 数组概述 • 申明数组 declare -a array array[xx] • 调用时 ${array[xx]} 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 30. 数组使用实例一 BOOKS[0]=”RHEL5.0” BOOKS[1]=”Windows 7” BOOKS[2]=”Unix” for IDX in 0 1 2 do printf “ %sn” “${BOOKS[IDX]}” done 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 31. • arrayZ=( one two three four five ) • echo ${arrayZ[@]:0} #one two three four five • echo ${arrayZ[@]:1} #two three four five • echo ${arrayZ[@]:1:2} #two three 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 32. 综合使用实例 • 在数组中查找所有的元素,找到想匹配的并将其移除(此处是 最短匹配) echo ${arrayZ[@]#t*e} #one two e four five • 同上(此处是最长匹配) echo ${arrayZ[@]##t*e} #one two four five 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710
  • 33. 谢谢! 任何问题请 email: yangwawa0323@163.com 指导老师:杨坤 QQ: 12238747 蓝狐教育系统培训中心 0731-84125710