Shell 编程
一、shell的初步理解
1、怎么去理解shell???
shell在英文中翻译为 "贝壳",在贝壳内部就是linux系统内核,在贝壳外部就是用户。
对于shell而言,就是用户跟内核之间的媒介。
2、shell命令
linux命令 指的是shell命令,大多数shell命令存放在/bin目录,当我们需要使用一个命令时,操作流程:
1)打开终端 Termial ---》Termial终端(终端进程)实际上运行了一个bash进程(bash命令解析器)
gec 4170 1 0 18:14 ? 00:00:00 gnome-terminal
gec 4177 4170 0 18:14 pts/0 00:00:00 bash
2)bash命令解析器会把bash命令提示符打印到终端上
gec@ubuntu:~$ --》命令行提示符,必须要有命令行,shell命令才会把bash解析器进行解析出来
--->每次输入命令之后,并且解析完成 都会输出一条命令提示符,等待下一次命令输入
3)所有在命令行上输入的命令,都是使用Bash解析器进行解析
---》需要按下回车,命令才会被送到Bash解析器进行解析
gec@ubuntu:~$ which bash
/bin/bash
二、shell脚本编程
1、什么是shell编程
shell编程就是通过shell语法将shell命令组合起来,写入到一个文件中。将来运行这个文件时,就会执行里面的每一行shell命令。这个文件称之为shell脚本文件。实现自动化和智能化。
2、C编程和shell编程区别
C语言程序 shell脚本程序
语法 C语言 shell语法
文件后缀 .c xxx.sh
文件存放位置 任意目录 除了共享目录之外,其他目录都可以,一般放在家目录
是否需要编译 gcc编译 不需要编译,但是需要给权限
3、为什么要学习shell脚本编程???
当前IT服务器上大部分都是linux服务器。linux服务器的日常维护 和管理 需要 linux运维工程师,让程序员写的代码能够高效、稳定、安全地在服务器上运行。
linux运维工程师:
- 安装操作系统 ubuntu centos
- 部署运行环境、网站后台
- 及时修复漏洞,防止服务器被攻击,包括linux本身漏洞和软件漏洞。
- 监控服务器压力,别让服务器宕机。
- 分析日志,及时发现代码或者环境问题,通知相关人员处理。
shell脚本就是实现linux系统自动化管理以及自动化运维所必备的工具,linux的底层以及基础应用软件的核心部分会涉及到shell脚本。
三、编写和运行第一个shell脚本程序
1、编写时需要注意
1) shell脚本没有main函数,也没有头文件。shell脚本文件是使用bash解析器进行解析,所以必须在shell脚本中的第一行指明解析器的路径:
#!/bin/bash
#! 是shell脚本特殊字符,后面跟着shell命令解析器的路径
2)shell脚本没有printf函数,要输出内容到终端上,必须使用shell命令 ---》echo NAME
echo - display a line of text -->在终端上显示一行文本
SYNOPSIS
echo [SHORT-OPTION]... [STRING]...
echo LONG-OPTION
-e enable interpretation of backslash escapes 解析字符串上的转义字符
比如:
gec@ubuntu:~$ echo "hell world"
hell world
gec@ubuntu:~$ echo -e "hell world\n"
hell world
2、在家目录下 编写第一个shell脚本程序 01hello.sh
#!/bin/bash
echo "hello world"
执行的时候:
gec@ubuntu:~/shelltest$ ./01hello.sh
bash: ./01hello.sh: Permission denied ---提示没有权限 (新建出来的脚本文件默认是没有权限的)
必须要给权限
chmod 777 01hello.sh
然后执行
./01hello.sh
练习1:写一个shell脚本程序,要求输出以下信息
GZ2166班 何永成来自广东
#!/bin/bash
echo "GZ2166班 何永成来自广东"
四、变量
1、shell变量不需要声明数据类型,所有的变量默认都是字符串类型
C语言 int a;
shell str
2、 shell语法中为变量赋值的时候,等号的左右两边不允许有空格
C语言 int a = 10;
shell str=helloworld
3、变量的引用,需要在变量的前面加入美元符号$
echo $str
4、变量的种类
1)自定义变量 str=hello a=20 c=100
2)系统环境变量 --env命令查看环境变量
SHELL=/bin/bash //命令解析器
USER=gec 当前用户名
PWD=/home/gec 当前所在的工作路径
HOME=/home/gec 家目录 cd
PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/arm/bin //当我们使用某个命令ls时,正常来说,系统会在当前目录下去查找有没有这个程序,如果找不到,那么就会去 PATH环境变量所保存的路径中去寻找这个程序,如果找到了,那么就会执行
使用命令改变环境变量:
export PWD=/
export PATH=$PATH:/home/gec/aa
5、位置变量(传递命令行参数和函数调用时传递参数)
./03val.sh aaa bbb
$0 表示 命令程序名 ./03val.sh
$1 $2 $3...... 表示第一个到后面的参数的名字
$1 --aaa
$2 --bbb
$# 表示命令行参数的个数(不包含程序名) 2
$? 表示前一个命令的退出状态(返回值)
shell命令执行成功:0 执行失败:非0
$* 包含所有命令行参数 aaa bbb
比如:
gec@ubuntu:~/shelltest$ ls --当前执行这个命令
01hello.sh 02val.sh 03val.sh
gec@ubuntu:~/shelltest$ echo $? ---使用位置变量去查看上一个命令是否执行成功
0 --》返回 0表示执行成功
gec@ubuntu:~/shelltest$ qweqweqweqw --当前执行这个命令
qweqweqweqw: command not found
gec@ubuntu:~/shelltest$ echo $?---使用位置变量去查看上一个命令是否执行成功
127 --》返回 非0表示执行失败
注意:
1)在脚本中设计的环境变量只在脚本以及子脚本范围内有效,
如果想要在外边的环境中生效,则需要在执行的时候,加上source
比如: 1.sh
#!/bin/bash
export PWD=/
---》执行的时候 source 1.sh
五、shell编程符号
1、双引号
“”---》作用:把某些东西 变成 “值”
1)例如字符串中有空格,则必须使用""
str=hello
str=hello world 不对
str="hello world" 正确
str=helloworld 正确
2)在 ""内对变量进行引用
str=hello
echo "$str world"
3)在""内部是可以使用shell命令,但是使用shell命令需要使用反引号``来扩住命令
#!/bin/bash
#echo "date" ---》结果:单纯输出 date字符串
echo "today is `date`"---》结果:today is Tue Nov 9 22:47:09 PST 2021
2、单引号
‘’---》在单引号里面的内容 看做是 纯粹的字符串
echo 'today is `date`' ---》结果: today is `date`
str=hello
echo '$str' -->结果:$str
3、反引号
` ---》把双引号中的命令标识出来,也就是说将反引号中的内容当成一个shell命令进行解析
echo "today is `date`"---》结果:today is Tue Nov 9 22:47:09 PST 2021
4、重定向符号
< << > >>
标准输入(0) 标准输出(1) 标准出错(2)
1)输出重定向 > >>
命令的输出结果 通常提交到标准输出设备(终端),但是也可以重新定个方向到其他位置,比如定位到文件中,这种方式称之为 输出重定向
在命令的后面添加>filename, 该命令(脚本)的输出就会写入到filename这个文件中,而不是写入终端
gec@ubuntu:~/shelltest$ ls -l >1.txt --》将ls -l 的命令结果重定向 到 1.txt文件中
gec@ubuntu:~/shelltest$ ls -l >>1.txt --》以追加的方式的将命令的结果重定向到1.txt文件中
2)输入重定向
命令的输入通常是从标准输入设备(键盘)中请求,但是也可以重新定个方向到其他位置,比如从一个文件中请求,这叫做输入重定向
命令 <filename 该命令所有的输入请求都来自filename
3)标准出错重定向
大部分错误的信息都写到一个终端里面,也可以重定向到文件中
命令 2>filename
gec@ubuntu:~/shelltest$ asdsdsdsdsd ---将错误的信息默认定位到终端上
asdsdsdsdsd: command not found
gec@ubuntu:~/shelltest$ adsdsdsdsdsdsd 2>1.txt --将错误的信息重定向 到 文本中 1.txt
六、算数运算符 expr
1、expr 主要是用于简单的整数计算,包括 加(+)减(-)乘(\*)除(/) 取余(%)
比如:
#!/bin/bash
a=20
b=10
ret=`expr $a + $b` (注意重点再注意:操作数与运算符,前后至少要有一个空格)
echo "ret:$ret"
练习: 编写一个shell程序, 实现 (20+20) *10的 结果
#!/bin/bash
a=20
b=20
ret=`expr $a + $b`
ret=`expr $ret \* 10`
echo "ret:$ret"
七、获取输入
read: 在shell表示 从键盘上获取输入
read str -->从键盘上获取输入的数据,存储到变量str
read -p "input data:" val1 val2 val3 -->从键盘上获取三个整数,并且分别保存到变量val1 val2 val3中
#!/bin/bash
read -p "input data:" val1 val2 val3
echo "val1:$val1"
echo "val2:$val2"
echo "val3:$val3"
注意:
1、以#号开头的行,就是注释行
2、多行注释 :
<<'CMD'
......
......
......
CMD
比如:
<<'abc' --从这里开始注释
echo "val1:$val1"
echo "val2:$val2"
echo "val3:$val3"
abc --到这里截止
练习2: 从键盘上获取三个同学的信息,并且打印出来
姓名 年龄
#!/bin/bash
read -p "请输入姓名和年龄" student1 age1
read -p "请输入姓名和年龄" student2 age2
echo "姓名:$student1 年龄:$age1"
echo "姓名:$student2 年龄:$age2"
八、test语句
test语句 可以测试 三种对象:字符串、整数、文件属性
1、字符串测试
= 测量两个字符串内容是否完成相同
!= 测量两个字符串内容是否不一样
-Z(zero) 测试字符串是否为空,为空,返回true
-n(null) 测试字符串是否不为空 ,不为空,返回 true
2、整数测试
a=10
b=20
a -eq b equal 测试两个整数是否相等
a -ne b not equal 测试两个整数是否不相等
a -gt b greater 测试 a是否大于b
a -ge b greater or equal 测试a是否大于等于b
a -lt b little 测试a是否小于b
a -le b little or equal 测试a是否小于等于b
3、文件测试
-d name 测试name 是否是一个目录 (dir)
-f name 测试name 是否为一个普通文件 (file)
-L name 测试name 是否为符号链接文件(Link)
-r name 测试Name文件是否存在 并且可读(read)
-w name 测试name文件是否存在并且可写(write)
-x name 测试文件是否存在并且可执行(excute)
-s name 测试name文件是否存在并且长度不为0(size)
file1 -nt file2 测试file1是否比file2更新 (newer than)
file1 -ot file2 测试file1是否比file2 更旧(older than)
test命令可以用[]来简写
test 表达式 <-->[ 表达式 ]
test的复合表达式
组合了两个或者两个以上的表达式称之为 复合表达式,你可以使用test([])内置的操作符,也可以使用条件操作符(&& || !)来实现
1)使用test内置的操作符
test expr1 "test_buildn" expr2
"test_buildn":
-a and
-o or
2)使用条件操作符(&& || !)
比如: test $A='1' && test $B='1'
[ $A='1' && $B='1' ]
判断一个输入的整数是否 奇数,如果是则打印 yes ,否则 打印 no
C语言写法:
int val;
if(val%2 == 0)
偶数
else
奇数
shell写法:
#!/bin/bash
read -p "input data:" val
if test `expr $val % 2` -eq 0;then
echo "no"
else
echo "yes"
fi
九、if分支语句
1、格式:
if command;then
语句列表
fi
if command;then
语句列表
else
fi
if command;then
语句列表1
elif command;then
语句列表2
elif command;then
语句列表3
else
语句列表4
fi
2、例子
从键盘上输入一个字符串,判断是否是 "hello",如果是 打印yes 如果不是打印no
#!/bin/bash
read -p "input str:" str
if test $str = "hello";then
echo "yes"
else
echo "no"
fi
练习3:编写一个shell脚本,从键盘上获取两个整数,比较大小,输出最大值
#!/bin/bash
read -p "input num:" a b
if test $a -ge $b;then
echo "a"
else
echo "b"
fi
练习4:编写一个shell脚本,判断一个文件是否存在
如果存在则打印文件的内容
如果不存在,则输出字符串报错 "error"
练习5:用shell编写脚本程序:读取变量dir,如果该变量代表的值是目录,则切换到该目录下,
并在该目录下创建空文件file.txt,将“hello world ”写到该文件中
如果该目录不存在则创建该目录并切换过去,并显示当前绝对路径