More Related Content Similar to Bash编程之变量高级篇 (20) 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
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
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
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
33. •
谢谢!
任何问题请 email:
yangwawa0323@163.com
指导老师:杨坤 QQ: 12238747
蓝狐教育系统培训中心 0731-84125710