马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
1.shell的初步明白
1.1 怎么明白shell
\quad shell在英文中翻译为"贝壳",在贝壳内部就是linux体系内核,在贝壳外部就是用户。对于shell而言,就是用户与内核之间的媒介。是用户跟内核通讯几种方式中的一种。
1.2 shell下令
\quad Linux下令指的是shell下令,大多数shell下令都是存放在/bin,当我们须要使用一个下令时,现实的流程:
- 1)打开一个Termial--》Termial终端实际上是运行了一个bash进程(bash命令解析器)
- china 2356 1743 0 11:42 ? 00:00:11 /usr/lib/gnome-terminal/gnome-terminal-serve
- china 2366 2356 0 11:42 pts/0 00:00:00 bash
- 2)bash命令解析器会把bash命令提示符打印到终端上
- china@ubuntu:~$ --》命令行提示符。必须要有命令行,shell命令才会被bash解析器解析出来
- --》每次输完命令并且解析之后都会输出一条命令行提示符,然后再次等待下一次命令输入
- 3)所有在命令行上输入的命令,都是使用bash解析器进行解析
- china@ubuntu:~$ ls ---当按下回车的时候,就会被送到bash解析器进行解析!
- bash解析器这个应用程序在系统中的位置:
- china@ubuntu:~$ which bash
- /bin/bash
复制代码 2.shell编程
2.1 什么是shell编程
\quad shell编程就是通过shell语法将shell下令组合起来,写入一个文件中。未来运行这个文件时,就会执行内里的每一行shell语法,这个文件称之为shell脚本文件。实现更加自动化和智能化。
2.2 C语言编程 和 shell编程的区别
C语言步伐shell脚本步伐语法C语言语法shell语法文件后缀xxx.cxxx.sh文件存放位置任意目录除了共享目录之外,一样平常放在家目录是否须要编译gcc编译不须要编译,但是须要给权限3.编写和运行第一个shell脚本步伐
3.1 编写时须要注意以下几点:
3.1.1 shell脚本没有main函数,没有头文件。shell脚本文件中是使用bash剖析器举行剖析,以是必须在shell脚本中的第一行指明剖析器的路径:
#!是shell脚本中特别标识符,反面必须跟着shell下令剖析器的路径
3.1.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 --> 解析字符串上的转义符号
- 比如:
- china@ubuntu:~$ echo "hello world\n"
- hello world\n
- china@ubuntu:~$ echo -e "hello world\n"
- hello world
复制代码 3.2 第一个shell步伐 hello.sh
- #!/bin/bash
- echo "hello world"
复制代码 3.3 怎样运行编写好的shell步伐
3.3.1 先给权限(由于默认是没有执行权限的)
- chmod 777 hello.sh 或者 chmod +x hello.sh
复制代码 3.3.2 执行
4.变量
4.1 shell变量不须要声明数据范例,全部的变量默认都是字符串范例
4.2 shell语法中为变量赋值时,等号的左右两边不允许有空格
- C语言 int a = 10;
- shell str=hello
- world
复制代码 4.3 变量的引用,须要在变量前面参加美元符号$
4.4 变量种类
4.4.1 自界说变量
4.4.2 体系环境变量----env下令查看环境变量
- HOME: 用户主目录
- PATH: 命令搜索路径
- LD_LIBRARY_PATH: 动态库搜索路径
- PWD: 当前路径
复制代码 使用下令改变环境变量:
- export PATH=$PATH:/home/china/xxx
- export PATH=/home/china/xxx
复制代码 4.5 位置变量(传递下令行参数和函数调用时传递参数)
- $0 体现下令步伐名 ./hello.sh
- $1,$2,$3...$9 体现第一个到第九个参数的名字 $1-->aaaa $2--->bbbb$# 体现下令行参数的个数(不包含脚本名) 2$* 包含全部下令行参数 aaaa bbbb $? 体现前一个下令的退出状态(返回值)shell下令执行乐成: 0 执行失败: 非0$$ 体现正在执行历程的ID号
复制代码 注意:
(1)在脚本中修改的环境变量只在脚本及子脚本范围内有效,要想其在外边环境中见效,则须要前面加source
(2)怎样使脚本(步伐)配景执行
a.脚本(步伐)反面加&符号,但是终端退出了,该历程也会竣事
b.假如想让终端退出后,历程仍在:
5.shell编程符号
5.1 双引号 --> 作用: 把某些东西 变成 “值”
5.1.1 例如字符串中有空格,则必须使用"“,假如没有空格,不加”"也可以
- str=hello
- 准确str="hello" 准确 str=hello
- world 不准确str="hello world" 准确
复制代码 5.1.2 在""内可以对变量举行引用
- str=hello
- echo "$str world"
复制代码 5.1.3 在""内部是可以使用shell下令,但是使用shell下令须要使用反引号``来括住下令
- china@ubuntu:~/shelldir$ date
- 2021年 08月 14日 星期六 20:36:11 CST
- echo "today is date" ---->结果:today is date
- echo "today is `date`" ---->结果:today is 2021年 08月 14日 星期六 20:37:56 CST
复制代码 5.2 单引号 —>在单引号内里的内容 看做是纯粹的字符串
- echo 'today is date' --->结果:today is datestr=hello
- echo '$str world' --->结果:$str world 不能在单引号内里引用变量
复制代码 5.3 反引号—>把双引号中的下令标识出来,也就是将反引号中的内容当成一个shell下令举行剖析
- echo "today is `date`" ---->结果:today is 2021年 08月 14日 星期六 20:37:56 CST
复制代码 5.4 重定向符号 < << > >>
标准输入(0)/标准输出(1)/标准输错(2) 体系默认打开的文件形貌符
5.4.1 输出重定向 > >>
\quad 下令的输出结果通常提交到标准输出装备(终端),但是也可以重新定个方向到其他位置,好比用一个文件来代替,这叫做输出重定向。在下令后添加>filename ,该下令(脚本)的输出就会写入到filename这个文件中,而不是写入终端。
- china@ubuntu:~/shelldir$ ls ---命令解析的结果输出在终端上
- 1.sh 2.sh a.txt
- china@ubuntu:~/shelldir$ ls >a.txt ---命令的输出结果重定向到文件a.txt中
- china@ubuntu:~/shelldir$ cat a.txt
- 1.sh
- 2.sh
- a.txt
- china@ubuntu:~/shelldir$ ls >>a.txt ---以追加的方式重定向到文件a.txt中
- china@ubuntu:~/shelldir$ cat a.txt
- 1.sh
- 2.sh
- a.txt
- 1.sh
- 2.sh
- a.txt
- china@ubuntu:~/shelldir$ echo "hello world">a.txt --将一个字符串"hello world" 输出重定向到文件a.txt中
- china@ubuntu:~/shelldir$ cat a.txt
- hello world
复制代码 5.4.2 输入重定向
\quad 下令的输入通常是从标准输入装备(键盘)中请求的,但是也可以重新定个方向到其他位置,好比从一个文件中请求,这叫做输入重定向。下令<filename 该下令全部的输入请求都来自filename。
- 比如:read str <1.txt 从1.txt中读取数据,存储到变量str中
复制代码 5.4.3 标准出错重定向
\quad unix下令把大部分错误信息都写到这个装备内里。一样平常环境下,标准出错装备和标准输出装备是同一个装备(默认为终端)。标准出错也可以重定向到文件
- 命令 2 > filename
- 命令 2 >> filename
- china@ubuntu:~/shelldir$ asdsds 2>a.txt --把出错信息重定向到文件a.txt中
- china@ubuntu:~/shelldir$ cat a.txt
- asdsds:未找到命令
复制代码 6.算术运算下令expr
expr紧张是用于简单的整数盘算,包罗 加(+)、减(-)、乘(*)、除(/)、取余(%)
- #!/bin/bash
- a=10b=20val=`expr $a + $b` (注意:利用数与运算符,前后至少要有一个空格)echo "val:$val" --->val:30
复制代码- #!/bin/bash
- a=10b=20 val=`expr $a + $b \* 4` (且不支持括号)echo "val:$val" --->val:90
复制代码 7.字符串处理处罚
盘算字符串字符个数
- str="hello world"
- echo "${#str}" -->11
复制代码 通配符:
- * 代表任意长度的任意字符
- ? 代表一个长度的任意字符
- [a-z]: 代表一个长度的a-z之内的字符
- [az]: 代表一个长度,只能匹配a或者z的内容
- [^az]: 代表一个指定范围a/z之外的字符 与[az]相反!
- %: 从右到左尽可能匹配少的字符
- %%: 从右到左尽可能匹配多的字符
- #: 从左到右尽可能匹配少的字符
- ##: 从左到右尽可能匹配多的字符
复制代码 8.获取输入
read:在shell体现从终端输入
- read val1
- read -p "input data:" val1 val2 val3
- read val<1.txt //从文本输入
复制代码 注意:
1、以#开头的行,就是解释行
2、多行解释:
9.if分支语句
9.1 条件语句
- 第一种:
- if command ; then
- ...语句列表
- fi
- 第二种:
- if command ; then
- ...语句列表
- else
- ...语句列表
- fi
- 第三种:
- if command ; then
- ...语句列表
- elif command ; then
- ...语句列表
- else
- ...语句列表
- fi
复制代码- eg:
- read var
- if [ $var = "hello" ] ; then
- echo "yes"
- else
- echo "no"
- fi
复制代码 如:从键盘上获取两个整数,比力巨细,输出最大值
- read -p "input two data:" val1 val2
- if [ $val1 -gt $val2 ];then
- echo "max:$val1"
- else
- echo "max:$val2"
- fi
复制代码 10.test语句
test语句可以测试三种对象:字符串、整数、文件属性
10.1 字符串测试
- = 测试两个字符串内容是否完全一样
- != 测试两个字符串内容是否不一样
- -Z(zero) 测试字符串是否为空,为空,返回true
- -n(null) 测试字符串是否不为空,不为空,返回true
复制代码 在测试字符串变量时,须要防止字符串为空的本领:
==引用变量后加一个额外的字符: ==
10.2 整数测试
- 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
复制代码 10.3 文件测试
- -d name 测试name是否是一个目录(dir)
- -f name 测试name是否是一个普通文件(file)
- -L name 测试name是否为符号链接文件(Link)
- -r name 测试name文件是否存在并可读(read)
- -w name 测试name文件是否存在并可写(write)
- -x name 测试name文件是否存在并可执行(excute)
- -s name 测试name文件是否存在并且长度不为0(size)
- f1 -nt f2 测试f1 是否比f2更新(newer than)
- f1 -ot f2 测试f1 是否比f2更旧(older than)
复制代码 test下令可以用[]来简写
- test expression <===> [ expression ]
复制代码 test的复合表达式
\quad 组合了两个或两个以上的表达式称为复合表达式,你可以用test([])内置的的利用符,也可以用条件利用符(&& || !)来实现
1)使用test内置的利用符
- test expr1 "test_buildin" expr2
- test_buildin:
- -a and
- -o or
复制代码 2)使用条件利用符(&& || !)
- test expr1 "op" test expr2
复制代码 如:
- test $A = '1' && test $B = '1'
- @ [ $A = '1' ] && [ $B = '1' ]
复制代码 11.多路分支语句
11.1 格式
- case expression in
- pattern1)
- ...语句列表
- ;; //作用类似与C语言的break,这里;;不能省
- pattern2)
- ....语句列表
- ;;
- patternn)
- ....语句列表
- ;;
- *) ---其他值
- ....语句列表
- ;;
- esac
复制代码 11.2 总结
1)expression 既可以是一个变量、一个数字、一个字符串,还可以是一个数学盘算表达式,或者是下令的执行结果,只要能够得到 expression 的值就可以。
2)pattern 可以是一个数字、一个字符串,以致是一个简单的正则表达式。
3)case语句真正的功能强盛之处在于它可以使用模式而不是固定的字符串匹配。一个模式是由一串正规字符和特别的通配符构成的字符串,该模式可以用正则表达式。
11.3 举例
例子1:
执行步伐后,从键盘中获取一个值
假如该值为1,则打印one
假如该值为2,则打印two
假如该值其他值,则打印error
- read val
- case $val in
- 1)
- echo "one"
- ;;
- 2)
- echo "two"
- ;;
- *)
- echo "error"
- ;;
- esac
复制代码 例子2:
- #!/bin/bash
- read -p "input data:" valcase $val in [0-9]) echo "this is 0-9" ;; [a-d]|[m-z]) echo "this is a-d m-z" ;; h*) echo "h....." ;; [-]*) echo "---------" ;; *) echo "other" ;;esac
复制代码 12.循环语句
12.1 for循环
格式:
- for 变量名 in 单词表
- do
- 语句列表
- done
复制代码 如:
- for val in 1 2 3 4 5
- do
- echo $val
- done
复制代码 执行结果:
- china@ubuntu:~/shelldir$ chmod 777 for.sh
- china@ubuntu:~/shelldir$ ./for.sh
- 1
- 2
- 3
- 4
- 5
复制代码 如:
- for val int $*
- do
- echo $val
- done
复制代码 执行结果:
- china@ubuntu:~/shelldir$ ./for.sh 1 2 3 4 5 6
- 1
- 2
- 3
- 4
- 5
- 6
复制代码 =>for也可以写成C风格相同的for循环
- for((i=1; i<=5; i++ ))
- do
- echo "$i"
- done
复制代码 //双圆括号(())使得shell步伐中可以使用C语言的for风格
例子:写一个脚本,求1到100的和
- sum=0
- for((i=1;i<=100;i++))
- do
- sum=`expr $sum + $i`
- done
- echo "sum:$sum"
复制代码 12.2 while循环
格式:
- while 命令或表达式
- do
- 语句列表
- done
- ===>也可以用C语言的while风格
- while(())
- do
- 语句列表
- done
复制代码 好比:从键盘上获取一个最小值和最大值,打印他们两个之间的全部取值
- read -p "min:" min
- read -p "max:" max
- while test $min -le $max
- do
- echo "$min"
- min=`expr $min + 1`
- done
复制代码 如:写一个脚本,求1到100的和
- sum=0
- i=1
- while [ $i -le 100 ]
- do
- sum=`expr $sum + $i `
- i=`expr $i + 1`
- done
- echo "sum:$sum"
复制代码 12.3 until
格式:
until与while功能相似,所差异的是只有当测试的下令或表达式的值为假时,才执行循环体中的下令列表。若条件成立则退出循环。这一点与while恰好相反。
12.4 break 和 continue
- break n跳出n层循环
- continue n 跳到n层循环语句的下一轮循环去
- break 和 continue 反面不加n,则和C语言内里的寄义一样
举例:
写一个脚本,实现可以不停地从键盘获取数据
假如获取的数据为 “exit” ,则退出
假如获取的数据小于100,则打印值
假如获取的数据是其他的,则打印 “other”
- #!/usr/bin/bash
- <<'aaa'
- while((1))
- do
- read -p "data:" data
-
- if test $data = "exit" ;then
- break
- elif [ $data -lt 100 ];then
- echo "$data"
- else
- echo "other"
- fi
-
- done
- aaa
- while((1))
- do
- read -p "data:" data
-
- case $data in
- exit)
- break
- ;;
- [0-9])
- echo "$data"
- ;;
- [0-9][0-9])
- echo "$data"
- ;;
- *)
- echo "other"
- ;;
- esac
- done
复制代码 13.函数
格式:
- function_name()
- {
- ...命令列表
- echo $1 $2 $3
- return 123
- }
复制代码 function_name:你自界说的函数名,名字的取法与C语言类似
函数的调用
- function_name arg1 arg2 arg3
复制代码 在函数内部 arg1==>$1 arg2==>$2 arg3==>$3
获取函数的返回值
- function_name arg1 arg2 arg3
- ret=$?
复制代码 注意:
1、函数的返回值的巨细不高出一个字节
2、SHELL没有变量作用域,假如出现重复变量名会认为是同一个。
好比:
- get_sum()
- {
- return `expr $1 + $2`
- }
- read var1;read var2
- get_sum $var1 $var2
- echo $?
复制代码 训练:编写一个脚本,封装一个函数实现比力两个数的最大值而且返回
- compare()
- {
- if test $1 -gt $2;then
- ret=$1
- else
- ret=$2
- fi
- }
- read -p "input two data:" val1 val2
- compare val1 val2
- echo "max:$ret"
复制代码 训练:编写一个脚本,实现一个函数求a+…+b的和
- sum=0
- get_sum()
- {
- for(( i=$1;i<=$2;i++ ))
- do
- sum=`expr $sum + $i`
- done
- }
- read var1 var2
- get_sum $var1 $var2
- echo $sum
复制代码 |