shell编程核心知识点

1、 执行脚本source和./的区别

source执行脚本时,不会创建子进程,而是在父进程中直接执行,如果脚本中有改变环境变量等操作,会影响到父进程的shell窗口,而 ./ 则不会。

2、替换运算符

${varname:-word}如果varname存在且非null,则返回varname的值;否则,返回word。
用途:如果变量未定义,则返回默认值。
范例:如果loginname未定义,则${loginname:-ollir}的值为ollir。
${varname:=word}如果varname存在且非null, 则返回varname的值,否则,设置其为word,然后返回其设置的值。
用途:如果变量未定义,则设置变量为word,并返回。
范例:如果loginname未定义,则${loginname:-ollir}的值为ollir,并且loginname变量被设置为ollir
${varname:?message}如果varname存在且非null,则返回varname的值,否则,打印“varname:message”,并退出当前的命令或脚本。如果省略message,shell会返回默认信息“parameter null or not set”。
用途:常用于捕获由于变量未定义而导致的错误。
范例:如果loginname未定义,则${loginname:?”undefined!”}则显示为loginname: undefined!,然后退出脚本。
${varname:+word}如果varname存在且非null,则返回word,否则返回null。用途:测试变量的存在性。
范例:如果loginname已定义,如${loginname:+1},返回1(也就真)

上述运算符内的冒号(:)是可选的。如果省略,则上述解释中的“存在且非null”改为“存在”即可,即变量运算符只判定变量是否存在。

3、模式匹配运算符

假设path的值为/home/prince/desktop/log.file.name

${varname#pattern}如果模式匹配于变量的开头处,则删除匹配的最短部分,并返回剩下的部分。
范例:${path#/*/}为prince/desktop/log.file.name
这个范例删除了字符串开头/之间的部分
${path#*/}为home/prince/desktop/log.file.name
${path#*.}为file.name
${varname##pattern} 如果模式匹配于变量的开头处,则删除匹配的最长部分,并返回剩下的部分。
范例:${path##/*/}为log.file.name
这个范例提取了文件路径中的文件名
${path##*/}为log.file.name
${path##*.}为name
${varname%pattern} 如果模式匹配于变量的结尾处,则删除匹配的最短部分,并返回剩下的部分。
范例:${path%/*}为/home/prince/desktop
${path%.*}为/home/prince/desktop/log.file
${varname%%pattern} 如果模式匹配于变量的结尾处,则删除匹配的最长部分,并返回剩下的部分。
范例:${path%%.*}为/home/prince/desktop/log
${varname/pattern/string}
${varname//pattern/string}
将varname中匹配模式的最长部分替换为string。
第一种格式中,只有匹配的第一部分被替换;第二种格式中,varname中所有匹配的部分都被替换。如果模式以#开头,则必须匹配varname的开头,如果模式以%开头,则必须匹配varname的结尾。如果string为空,则匹配部分被删除。如果varname为@或者*,操作被依次应用于每个位置参数,并且扩展为结果列表。
范例:${path//prince/ollir}则为:
/home/ollir/desktop/log.file.name
这个范例将字符串prince替换为ollir

4、shell中的常见参数引用

$0, $1, $2, ...	表示系统传给脚本程序或脚本程序传给函数的第 0个、第1个、第2个等参数。其中 $0表示 shell  文件的名称。
$# 表示脚本程序的命令参数个数或函数的参数个数
$? 表示脚本程序或函数的返回状态值,正常为0,否则为非零的错误号
$*	以一个单字符串显示所有向脚本传递的参数。如"$*"用「"」括起来的情况、以"$1 $2$n"的形式输出所有参数。
$@	与$*相同,但是使用时加引号,并在引号中返回每个参数。如"$@"用「"」括起来的情况、以"$1" "$2""$n" 的形式输出所有参数。
$$    脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$- 显示Shell使用的当前选项,与set命令功能相同

$* 与 $@ 区别:

  • 相同点:都是引用所有参数。
  • 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 ” * ” 等价于 “1 2 3”(传递了一个参数),而 “@” 等价于 “1” “2” “3”(传递了三个参数)。

实例分析

    #!/bin/bash

    echo "-- \$* 演示 ---"
    for i in "$*"; do
        echo $i
    done

    echo "-- \$@ 演示 ---"
    for i in "$@"; do
        echo $i
    done
执行脚本,输出结果如下所示:
$ chmod +x test.sh 
$ ./test.sh 1 2 3
-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3

5、数组

使用@ 或 * 可以获取数组中的所有元素,例如${my_array[*]}、${my_array[@]}
使用#获取数组的长度,要配合@或一起使用,例如${#my_array[]}、${#my_array[@]}

$()的用法
利用 $() 符号可以把一个命令的执行结果赋值给变量

6、算术运算

当把一个算术表达式的结果赋值给一个变量是不行的。

~]# a=1+2 
~]# echo $a 
1+2 

而应该采取下面几种方式之一:

~]# let a=1+2 
~]# echo $a 
3 
~]# a=$((2+3)) 
~]# echo $a 
5 
~]#  declare -i a 
~]#  a=10+1 
~]# echo $a 
11

假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例
+ 加法 expr $a + $b 结果为 30。
- 减法 expr $a - $b 结果为 -10。
* 乘法 expr $a \* $b 结果为 200。
/ 除法 expr $b / $a 结果为 2。
% 取余 expr $b % $a 结果为 0。
= 赋值 a=$b 将把变量 b 的值赋给 a。
== 相等。用于比较两个数字,相同则返回 true。[ $a == $b ] 返回 false。
!= 不相等。用于比较两个数字,不相同则返回 true。[ $a != $b ] 返回 true。

7、关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例

-eq 等于  [ $a -eq $b ] 返回 false-ne 不等于 [ $a -ne $b ] 返回 true-gt 大于, [ $a -gt $b ] 返回 false-lt 小于  [ $a -lt $b ] 返回 true。
-ge 大于等于    [ $a -ge $b ] 返回 false。
-le 小于等于    [ $a -le $b ] 返回 true。
<   小于 (需要双括号 ),    如:(("$a" < "$b"))  
<=      小于等于 (需要双括号 ),  如:(("$a" <= "$b"))  
>   大于 (需要双括号 ),    如:(("$a" > "$b"))  
>=      大于等于 (需要双括号 ),  如:(("$a" >= "$b"))

8、布尔运算符

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例

!   非运算,表达式为 true 则返回 false,否则返回 true。  [ ! false ] 返回 true。
-o  或运算,有一个表达式为 true 则返回 true。  [ $a -lt 20 -o $b -gt 100 ] 返回 true-a  与运算,两个表达式都为 true 才返回 true。  [ $a -lt 20 -a $b -gt 100 ] 返回 false

9、逻辑运算符

以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 说明 举例

&&  逻辑的AND  [[ $a -lt 100 && $b -gt 100 ]] 返回 false
||  逻辑的OR   [[ $a -lt 100 || $b -gt 100 ]] 返回 true

10、字符串运算符

下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:
运算符 说明 举例

=或者==   检测两个字符串是否相等,相等返回 true。[ $a = $b ]返回false。
!=       检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回true。
<        检验左边的字符串是否小于右边的,只能用于[[ ]]中,[[ $a < $b ]]或者[ $a \< $b ]返回true
>        与<效果相反 ,只能用于 [[ ]] 中,[[ $a < $b ]]或者[ $a \> $b ]返回false
-z       检测字符串长度是否为0(是否为空),为0返回 true。[ -z $a ] 返回 false。
-n       检测字符串长度是否为0(是否非空),不为0返回 true。[ -n $a ] 返回 true。
str      检测字符串是否为空,不为空返回 true。[ $a ] 返回 true

11、文件测试运算符

文件测试运算符用于检测 Unix 文件的各种属性。
操作符 说明 举例

-b file 检测文件是否是块设备文件,如果是,则返回 true。  [ -b $file ] 返回 false-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。    [ -f $file ] 返回 true-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。  [ -g $file ] 返回 false-h file 检测文件是否为符号链接,如果是,则返回true 
-L file 同-h 
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。  [ -k $file ] 返回 false-p file 检测文件是否是有名管道,如果是,则返回 true。   [ -p $file ] 返回 false-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。  [ -u $file ] 返回 false-r file 检测文件是否可读,如果是,则返回 true。  [ -r $file ] 返回 true-w file 检测文件是否可写,如果是,则返回 true。  [ -w $file ] 返回 true-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true-S file 检测文件是否为套接字(socket),如果是,返回true   
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true-e file 检测文件(包括目录)是否存在,如果是,则返回 true。    [ -e $file ] 返回 true-O file 检测你是否是文件的所有者,如果是,返回true 
-G file 检测文件的组ID是否匹配你的ID,如果是,返回true 
file1 –nt file2 检测file1是否比file2新,如果是,返回true 
file1 –ot file2 检测file1是否比file2旧,如果是,返回true 

12、if语句

使用 if 语句的语法格式如下:

if condition1_test; then 
  action 
elif condition2_test; then 
  action 
fi 

在 bash shell 程序中,条件测试是一个完整的语句,当与 then在同一行使用的时候,要加分号。如果条件测试和 then 分为两行,则可以不用加分号而使用下面的语句形式。

if condition1_test 
then 
action1 
elif condition2_test 
then 
action2 
fi 

条件测试部分的逻辑表达式可以有下面几种方式:

  • 放置在 test 关键字之后、
  • 放置于 [ ]中、
  • 放置于 [[ ]] 中、
  • 放置于 (( )) 中。

其中 test 条件 等价于 [ ] 的用法。 [ ] 及 [[ ]] 可以放置字符串比较逻辑表达式、文件判断表达式以及数值条件表达式,使用时,注意逻辑运算符两侧及判断表达式两侧要留有空格,而 (( )) 用于数值比较逻辑表达式。在用法上, ksh 一般使用 [[ ]] 及 (( )) ,bash shell 对这几种用法都支持,一般使用 [ ] 。

13、case语句

语法:

case var in     var变量
    patten 1)   匹配模式1 a|b|c  |or类似
    command...  需要执行的命令
    ;;      命令执行完毕
    patten 2)
    command...
    ;;
    *)      默认值,没有匹配的模式
    command...  
    ;;
esac

14、for循环

语法

for name [in list]    #遍历list中所有的对象
do
….            #执行与$name相关的操作
done

注意in list可以省略,省略时默认是in “$@”,即命令行参数的引用列表

第一类:数字性循环

for1-1.sh
#!/bin/bash       
for((i=1;i<=10;i++));  
do   
echo $(expr $i \* 3 + 1);  
done

for1-2.sh
#!/bin/bash  
for i in $(seq 1 10)  
do   
echo $(expr $i \* 3 + 1);  
done  

for1-3.sh
#!/bin/bash   
for i in {1..10}  
do  
echo $(expr $i \* 3 + 1);  
done  

for1-4.sh
#!/bin/bash  
awk 'BEGIN{for(i=1; i<=10; i++) print i}'  

第二类:字符性循环

for2-1.sh
#!/bin/bash  
for i in `ls`;  
do   
echo $i is file name\! ;  
done  

for2-2.sh
#!/bin/bash  
for i in $* ;  
do  
echo $i is input chart\! ;  
done  

for2-3.sh
#!/bin/bash  
for i in f1 f2 f3 ;  
do  
echo $i is appoint ;  
done  

for2-4.sh
#!/bin/bash  
list="rootfs usr data data2"  
for i in $list;  
do  
echo $i is appoint ;  
done  

第三类:路径查找

for3-1.sh
#!/bin/bash  
for file in /proc/*;  
do  
echo $file is file path \! ;  
done  

for3-2.sh
#!/bin/bash  
for file in $(ls *.sh)  
do  
echo $file is file path \! ;  
done  

14、while/until循环

语法

while condition
do
….
done

until condition
do
….
done

在while语句中,当condition的退出状态为真时,循环继续运行,否则退出循环
在until语句中,当condition的退出状态为真时,退出循环,否则继续执行循环

当循环体的嵌套次数超过1层时,可以传给break或continue参数,来控制它们跳出或者继续几层循环

while condition1             #第一层循环
do
….
while condition2         #第二层循环
do
    …..
    break 2            #跳出两层循环
done
done

shift命令
shift处理命令参数时,截取第一个位置参数,而将其他的未知参数左移,$#的值会逐渐减小,shift可以接受可选参数,用以制定一次要移动几位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值