Shell 小结
1. 打开文本编辑器(可以使用 vi/vim命令来创建),新建一个test.sh,扩展名为sh(sh 代表shell),
例如:
#!/bin/bash
echo "Hello world"
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种shell
运行Shell脚本的两种方法:
1. 作为可执行的程序
chmod +x ./test.sh
./test.sh
2. 作为解释器参数
/bin/sh test.sh
2. Shell变量
注意:变量名和等号之间不能有空格
2.1 命名只能使用英文字母,数字和下划线,首字符不能以数字开头
2.2 中间不能有空格,可以使用下划线(_)
2.3 不能使用标点符号
2.4 不能使用bash里的关键字
例如:
_var=123 =>正确
LD_123_asd=sads =>正确
?bad=2345 =>错误
3. 使用变量
使用一个定义过的变量,只要在变量名前面加美元符号即可,如:
your_name=qinjx
echo $your_name
echo ${your_name}
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如:
echo "my name is ${your_name}21" => my name is qinjx 21
如果不给your_name加花括号的话,写成echo "my name is $your_name21" ,解释器就会把$your_name21当作一个变量(这个变量未定义)
只读变量
使用readonly命令可以将变量定义为只读变量,只读变量的指不能被改变,例如:
#!/bin/bash
myUrl="http://www.google.com"
readonly myUrl
myUrl="http://www.runoob.com"
=> 运行脚本,执行结果如下:
/bin/sh:NAME: This variable read only.
删除变量
使用unset命令可以删除变量,语法:
unset 变量名
变量被删除后不能再次使用,unset命令不能删除只读变量
变量类型:
运行shell时,会同时出现三种变量:
1) 局部变量:局部变量在脚本或者命令中定义,仅在当前shell中有效,其他shell启动的程序不能访问局部变量
2) 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。
必要的时候shell脚本也可以定义环境变量。
3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,
这些变量保证了shell的正常运行
4. shell 字符串
字符串可以用单引号,也可以用双引号,也可以不用引号
4.1 单引号
str='this is string'
单引号字符串的限制:
1) 单引号的任何字符都会原样输出,单引号字符串中的变量是无效的
2) 单引号字符串中不能出现单独一个的单引号(对单引号使用转义字符后也不行),可成对出现,作为字符串拼接作用
4.2 双引号
your_name='runoob'
str="hello,I know you are \"$your_name\" ! \n "
echo -e $str
输出结果:
Hello, I know you are "runoob"
双引号的优点:
1) 双引号可以有变量
2) 双引号里可以出现转义字符
4.3 拼接字符串
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
输出结果为:
hello, runoob ! hello, runoob !
# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
输出结果为:
hello, runoob ! hello, ${your_name} !
4.4 获取字符串的长度
string="abcd"
echo ${string} =>输出4
4.5 提取子字符串
从下面实例从字符串第2个字符开始截取4个字符
string="runoob is a great site"
echo ${string:1:4} =>输出 unoo
注意: 第一个字符的索引值为0
4.6 查找子字符串
查找字符i或者o的位置(哪个字母在前就计算哪个)
string="runoob is a great site"
echo `expr index "$string" io` => 输出4
5. Shell数组
5.1 定义数组,用括号来表示数组,数组元素用"空格"符号分割开来,形式为:
数组名=(值1 值2 值3 ... 值n)
例如:
array_name=(value0 value1 value2 value3)
5.2 读取数组
读取数组元素值的一般格式是:
${数组[下标]}
例如:
valuen=${array_name[n]}
使用@符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}
5.3 获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
取得数组元素的个数
length=${#array_name[@]}
或者 length=${#array_name[*]}
获取数组单个元素的长度
lengthn=${#array_name[n]}
6. Shell注释
单行注释:以 # 开头的行是注释,会被解释器忽略
多行注释:
多行注释还可以使用如下格式:
:<<EOF
注释内容...
注释内容...
EOF
EOF也可以使用其他符号代替
:<<!
注释内容...
注释内容...
!
7. Shell传递参数
在执行shell脚本时,向脚本传递参数,脚本内获取的参数的格式为:$n.n代表第n个数字,1为执行脚本的第一个参数,2为执行脚本的第二参数,以此类推...
例如: #!/bin/bash
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
=> 执行
chmod +x test.sh
$ ./test.sh 1 2 3
=> 输出
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程的ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数
$- 显示Shell使用的当前选项
$? 显示最后的退出状态.0表示没有错误,其他任何值表示有错误
$*与$@的区别:
相同点:都是引用所有参数
不同点:只有在双引号中体现出来.
假设在脚本运行时写了三个参数1,2,3 则"*"等价于"1 2 3"(传递一个参数),而"@"等价于"1" "2" "3"(传递了三个参数)
例如:
#!/bin/bash
for i in "$*" ;
do
echo $i
done
for i in "$@" ;
do
echo $i
done
=> 执行脚本
chmod +x test.sh
./test.sh 1 2 3
=> 输出
1 2 3
1
2
3
8. Shell基本运算符
算数运算符
关系运算符
布尔运算符
字符串运算符
文件测试运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如awk和expr
expr是一款表达式计算工具,使用它能完成表达式的求值操作
#!/bin//bash
val=`expr 2 + 2`
echo "两数之和为:$val"
执行脚本,输出结果: 两数之和为:4
注意:1. 表达式和运算符之间要有空格,例如2+2是不对的,必须写成 2 + 2
2. 完整的表达式要被飘号 ` ` 包括,这个不是常用的单引号
算术运算符:
假定变量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
注意: 条件表达式要放在中括号之间,并且要有空格,例如:[$a==$b]是错误的,必须写成 [ $a == $b ]
关系运算符
关系运算符只支持数字,不支持字符串除非字符串的值是数字
假定变量a为10,变量b为20:
-eq 检测两个数是否相等,相等返回true [ $a -eq $b ] => false
-ne 检测两个数是否不相等,不相等返回true [ $a -ne $b ] => true
-gt 检测左边的数是否大于右边,如果是,返回true [ $a -gt $b ] => false
-lt 检测左边的数是否小于右边的,如果是,返回true [ $a -lt $b ] => true
-ge 检测左边的数是否大于 等于 右边,如果是,返回true [ $a -ge $b ] => false
-le 检测左边的数是否小于 等于 右边的,如果是,返回true [ $a -le $b ] => true
布尔运算符
假定变量a为10,变量b为20:
! 非运算
-o 或运算
-a 与运算
逻辑运算符
&& 逻辑的and
|| 逻辑的OR
字符串运算符
假定变量a为"abc",b为"efg"
= 检测两个字符串是否相等,相等返回true [ $a = $b ] => false
!= 检测两发个字符串是否相等,不相等返回true [ $a != $b ] => true
-z 检测字符串长度是否为0,为0返回true [ -z $a ] => false
-n 检测字符串长度是否不为0,不为0返回true [ -n $a ] => true
$ 检测字符串是否为空,不为空返回true [ $a ] => true
文件测试运算符
-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。
-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 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。
其他检查符:
-S: 判断某文件是否 socket。
-L: 检测文件是否存在并且是一个符号链接。
9. echo命令
1. 显示普通字符串
2. 显示转义字符
echo "\"It is a test \""
输出: "It is a test"
3. 显示变量
read命令从标准输入中读取一行,并把输入行的每个字段的值指定给shell变量
#!/bin//bash
read name
echo "$name is a test"
输出:
OK #标准输入
OK It is a test
4. 显示换行
echo -e "OK! \n" # -e 开启转义
echo "It is a test"
输出:
OK!
It is a test
5. 显示不换行
#!/bin/bash
echo -e "OK! \c"
echo "It is a test"
输出:
OK!It is a test
6. 显示结果定向文件
echo "It is a test" > mylife
7. 原样输出字符串,不进行转义或取变量(用单引号)
echo '$name\"'
输出:
$name\"
8. 显示命令执行结果
echo `date`
10. prinft输出命令
语法:
prinft format-string [arguments...]
参数说明:
format-string:为格式控制字符串
arguments:为参数列表
例如:
#!/bin/bash
prinft "%-10s %-8s %-4s\n" 姓名 性别 体重kg
prinft "%-10s %-8s %-4f\n" 郭靖 男 66.12
prinft "%-10s %-8s %-4f\n" 杨过 男 48.65
prinft "%-10s %-8s %-4f\n" 郭芙 女 47.56
输出:
姓名 性别 体重kg
郭靖 男 66.12
杨过 男 48.65
郭芙 女 47.56
11. 流程控制
if else
if语法:
if condition
then
command1
command2
command3
...
fi
if else语法:
if condition
then
command1
command2
command3
...
else
command
fi
for 循环
语法:
for var in item1 item2 ... itemN
do
command1
command2
command3
...
done
while 语句
while condition
do
command
done
无限循环
语法:
while :
do
command
done
或者
while true
do
command
done
或者
for((;;))
until 循环
until condition
do
command
done
condition一般为表达式,如果返回值为false,则继续执行循环体内的语句,否则挑出循环
case
case语句为多选择语句,可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令
case 值 in
模式1)
command1
command2
...
;;
模式2)
command1
command2
...
;;
esac
跳出循环
break
例如
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
12. 函数
[ function ] funname[()]
{
action;
[ return int; ]
}
说明:
1. 可以带function fun()定义,也可以直接fun()定义,不带任何参数,
2. 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值.return后跟数值n(0-255)