Shell编程
[
1.简介
shell脚本执行方式shell是一个用C语言编写的程序,通过shell用户可以访问系统内核服务。
1.2新建一个shell
新建hello.sh文件
#!/bin/bash
echo ‘hello world’
如果你希望查看当前Linxe的默认shell,那么可以输出shell环境变量
[root@node1 shell]# echo KaTeX parse error: Expected 'EOF', got '#' at position 442: … [root@node1 ~]#̲ /export/shell/…((运算式))”或“$[运算式]”方式运算
1.4.1用户变量
定义变量
在对变量赋予字符串值时,建议使用引号将其包裹。如果字符串中存在
访问变量;
[root@node1 ~]# usernmae=“itcast”
[root@node1 ~]# echo KaTeX parse error: Expected 'EOF', got '#' at position 16: usernamedb.log #̲这种方式不可以
.…username"db.log #可以
itcastdb.log
[root@node1 ~]# echo KaTeX parse error: Expected 'EOF', got '#' at position 18: …sername}db.log #̲可以
itcast…{num},string=KaTeX parse error: Expected 'EOF', got '#' at position 45: …ot@node1 shell]#̲ sh test1.sh
…(linux命令)或者KaTeX parse error: Expected 'EOF', got '#' at position 61: …test2.sh
#̲!/bin/bash
…(pwd) #将当前的绝对路径赋值给pwd_string变量
date_string=date
#将当前时间赋值给date_string变量,注意这里使用的是反引号
echo “hello, $name”
echo $pwd_string
echo $date_string
1.4.2只读变量
使用readonly命令可以将变量定义为只读变量,只读变量的值不能被改变。
下面的例子尝试更改只读变量,结果报错;
readonly myUrl
1.4.3删除变量
使用unset命令可以删除变量。语法:
unset variable_name
变量被删除后不能再次使用,unset命令不能删除只读变量
1.4.4自定义环境变量
export SERVICE_HOST=www.itcast.cn
1.4.5特殊变量
我们可以在执行shell脚本时,向脚本传递参数,这时候可以使用特殊变量来获取参数,shell常用的特殊变量如下:
变量 解释
$# 命令行参数的个数
$n $1表示第一个参数,$2表示第二个参数,以此类推
$0 当前程序的名称
$? 前一个命令或许或函数的返回码
$* 以“参数1 参数2 。。。”形式保存所有参数
$@ 以“参数1”“参数2”。。。形式保存所有参数
$$ 本程序的(进程ID号)PID
$! 上一个命令的PID
实例:
以下实例我们向脚本传递三个参数,并分别输出,其中 $0 为执行的文件名:
test5.sh
#!/bin/bash
echo “Shell 传递参数实例!”;
echo “执行的文件名:$0”;
echo “第一个参数为:$1”;
echo “第二个参数为:$2”;
echo “第三个参数为:3";echo"参数个数为:3";
echo "参数个数为:3";echo"参数个数为:#”;
echo “传递的参数作为一个字符串显示*:$";
$ 与 $@ 区别:
相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " ∗"等价于"123"(传递了一个参数),而"* " 等价于 "1 2 3"(传递了一个参数),而 "∗"等价于"123"(传递了一个参数),而"@” 等价于 “1” “2” “3”(传递了三个参数)。
1.5字符串
字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥)
1.5.1获取字符串长度
test8.sh
#!/bin/bash
string = “jobs”
echo ${string} # 输出结果: jobs
echo ${#string} # 输出结果: 4
1.5.2提取子字符串
索引为2的字符开始截取4个字符
test9.sh
#!/bin/bash
string = “敢于亮剑绝不后退”
echo KaTeX parse error: Expected 'EOF', got '#' at position 14: {string:2:2} #̲输出结果为:亮剑
1.…string" io # 输出是: 1 注意: 以上脚本中
是反引号(Esc下面的),而不是单引号 ',不要看错了哦。
1.6算术运算符
1.6.1
运算符 说明 举例
+ 加法 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 ]。
1.7流程控制
Shell提供了丰富的语句判断方式,包括数字,字符串和文件。
1.7.1语句判断
数字:
运算符 说明
-eq 检测两个数是否相等,相等返回 true。
-ne 检测两个数是否不相等,不相等返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。
字符串:
判断符 说明
-n STRING 字符串长度不为零
-z STRING 字符串长度为0
= 判断两个字符串是否一样
!= 判断两个字符串是否不一样
文件:
判断符 说明
-f 存在且是普通文件
-d 存在且是目录
-h 存在且是符号链接
-e 文件存在
–r 文件存在并且可读
–w 文件存在并且可写
–x 文件存在并且可执行
if语句:if 语句语法格式:
if condition
then
command1
command2
fi
例子:1)判断当前系统是否有多个ssh进程,如果有则打印true
#!/bin/bash
if [ $(ps -ef | grep -c “ssh”) -gt 1 ]
then
echo “true”
fi
解释:grep -c 用来统计字符串出现的次数
2)判断/media/cdrom文件是否存在,若不存在就去创建这个目录
#!/bin/bash
DIR=“/media/cdrom”
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi
if else
if else 语法格式:
if else-if else
1.8select 简介
select 表达式是bash的一种扩展应用,擅长于交互场合。用户可以从一组不同的值中进行选择:
select var in … ;
do
commond
done
… now $var can be used …
注意:
select 是一个无限循环,因此要记得用break命令退出循环,或用exit命令终止脚本
实例
下面是一个简单的示例:
test37.sh
#!/bin/bash
echo “What is your favourite OS?”
PS3=“Please enter your choice:”
select var in “Linux” “Gnu Hurd” “Free BSD” “Other”
do
break;
done
echo “You have selected $var”
这里PS3作为select语句的shell界面提示符,注意:PS3一定要定义在select语句的前面
该脚本的运行结果如下:
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
Please enter your choice:3
You have selected Free BSD
select和case的综合练习
test38.sh
#!/bin/bash
echo “你想学习什么语言?”
PS3=“请输入你的选择:” # 设置提示字符串
select var in java c++ shell python;
do
case KaTeX parse error: Expected 'EOF', got '#' at position 275: … break #̲ 如果这里没有break 将会…var"
1.7加载其她文件的变量
和其他语言一样,shell也可以包含外部脚本。这样可以很方便的封装一些公用代码作为一个独立文件
shell文件包含的语法格式如下:
.shellname # 注意点号(.)和文件名中间有一空格
或
source filename
练习:
定义两个文件demo1.sh 和demo2.sh 在test1中定义一个变量arr=(java c++ shell),在demod2中对arr进行循环打印输出。
第一步: vim demo1.sh
#!/bin/bash
my_arr=(AA BB CC)
第二步: vim demo2.sh
#!/bin/bash
source ./test1.sh # 加载test1.sh 的文件内容
for var in ${my_arr[*]}
do
echo $var
done
第三步:执行demo2.sh
sh demo2.sh
好处:
1、数据源和业务处理分离
2、复用代码扩展性更强
]