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可以接受可选参数,用以制定一次要移动几位