初识shell编程
一.认识shell
1.什么是shell
Shell 是一个命令行解释器,,他为用户提供一个向Linux内核发送请求以便运行程序的界面系统,用户可以用shell来启动,挂起,关闭甚至停止编写一些程序.
2.shell的编写
1. shell以#!/bin/bash开头 (告诉系统用那个shell)
3.shell的执行
1. 让文件有可执行权限: chmod u=rxw 文件名
2. 执行
方式一:
- 相对路径: ./文件名称
- 绝对路径: ./etc/xx/xx
方式二:
不需要文件有可执行权限,直接:sh 文件路径
方式一用的比价多
二.shell的变量介绍
1.shell变量介绍
1.Linux Shell中变量分为系统变量和用户自定义变量
2.系统变量:系统定义好的:$HOME,$PWD,$PATH,$USER等,比如echo $PATH
3.查看系统所有环境变量: set
4.shell用户自定义变量:
1. 定义变量: 变量名=变量值
2. 撤销变量unset
3. 静态变量: 静态变量不能撤销
2.变量的命名规则
1.变量名称可以由字母,数字,下划线组成,但是不能以数字开头
2.等号两侧不能有空格
3.变量名一般习惯大写
3.将命令的返回值赋值给变量
1. A=`ls /home ` 将命令执行结构赋值给A, echo $A
2. A=$(ls /home) 等价于反引号 echo 'A=$A'
4.使用变量
使用一个定义过的变量,只要在变量名前面加美元符号($)即可,如:
your_name="lalal" echo $your_name echo ${your_name}
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
for skill in C PHP Python Java do echo "I am good at ${skill}Script" done
如果不给skill变量加花括号,写成echo "I am good at $skillScript"
,解释器就会把$skillScript
当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
推荐给所有变量加上花括号,这是个好的编程习惯。
5.命令替换
命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。
语法:
`command`
注意是反引号,不是单引号,这个键位于 Esc 键下方。
下面的例子中,将命令执行结果保存在变量中:
#!/bin/bash DATE=`date` echo "Date is $DATE"
6.变量替换
变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值。
可以使用的变量替换形式:
形式 | 说明 |
---|---|
${var} |
变量本来的值 |
${var:-word} |
如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。 |
${var:=word} |
如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。 |
${var:?message} |
如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。若此替换出现在Shell脚本中,那么脚本将停止运行。 |
${var:+word} |
如果变量 var 被定义,那么返回 word,但不改变 var 的值。 |
三.设置环境变量
1.基本语法
1.export 变量名=变量值 (将shell变量输出为一个环境变量)
2.source 配置文件 (刷新配置文件,让设置生效)
3.echo $变量名 (查询环境变量的值)
2.位置参数
1. 基本语法:$n(功能描述:n为数字,$0代表本身,$1~$9代表第一到第九个参数,十以上的参数需要用花括号包含${10},
2. $* 这个变量代表命令行中所有的参数,$*把所有参数看成一个和整体
3. $@这个变量也代表命令行中所有参数,不过把每个参数区分对待
4. $# 这个变量代表命令行所有参数的个数
*
和 $@
的区别
$*
和 $@
都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n"
的形式输出所有参数。
但是当它们被双引号(" ")包含时,"$*
" 会将所有的参数作为一个整体,以"$1 $2 … $n
"的形式输出所有参数;"$@
" 会将各个参数分开,以"$1" "$2" … "$n"
的形式输出所有参数。
四.预定义变量
shell设计者预先设计好的变量,可以在shell脚本中直接是使用:
1. $$ 当前进程号
2. $! 后台运行的最后一个进程的进程号
3.$? 最后一次执行命令返回的状态 0你代表执行成功,非0代表不正确(所谓退出状态,就是上一个命令执行后的返回结果)
退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。
不过,也有一些命令返回其他值,表示不同类型的错误。
五.运算符
1.基本语法
1. "$((运算式))" 或者 $[运算式]
2.expr m + n
注意:expr和运算符之间要有空格
3.expr m - n
4.expr \*,/,% 乘除取余,第一个值转义符
2.关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
#!/bin/sh a=10 b=20 if [ $a -eq $b ] then echo "$a -eq $b : a is equal to b" else echo "$a -eq $b: a is not equal to b" fi
缩成一行可以这样:
a=10;b=20;if [ $a -eq $b ];then echo "$a -eq $b : a is equal to b"; else echo "$a -eq $b: a is not equal to b"; fi
这里缩写,主要是为了让大家注意:
- if后面直到then前面的分号结束,都是有空格的:
if [ $a -eq $b ]
3.布尔运算符
布尔运算符列表
运算符 说明 ! 非运算,表达式为 true 则返回 false,否则返回 true。 -o 或运算(or),有一个表达式为 true 则返回 true。 -a 与运算(and),两个表达式都为 true 才返回 true。
六.判断语句
1.基本语法
[condition] 注意condition前后要有空格
非空返回true,可使用$?验证(0为true,>1为false)
2.常用判断条件:
1.数字
-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。 |
2.文件测试运算符列表
-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。 |
3.字符串运算符列表
运算符 说明 举例 = 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。 != 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。 -z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。 -n 检测字符串长度是否为0,不为0返回 true。 [ -n $a ] 返回 true。 str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。
实例:
七.流程控制
1.if流程控制
方式一:
if [condition];then
程序
fi
方式二:
if [condition]
then
程序
elif [condition]
then
程序
fi
2.case流程控制
case $变量名 in
"值1")
如果变量值等于值1执行这条语句
echo "xxx"
;;
"值2")
echo "yy"
如果变量值等于值2执行这条语句
;;
*)
其他所有变量值执行这条
;;
esac
需要注意的是: 取值后面必须为关键字 in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;
。;;
与其他语言中的 break
类似,意思是跳到整个 case
语句的最后。
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 *
捕获该值,再执行后面的命令。
3.for循环流程控制
for 变量 in 值1 值2 值3
do
程序
done
和python一样,遍历
for((初始值,循环控制条件,变量变化))
do
程序
done
示例:
#!/bin/bash/ for value in 1 2 3 4 5 do echo "The value is $value" done
顺序输出字符串中的字符:
for str in 'This is a string' do echo $str done
遍历目录下的文件:
#!/bin/bash for FILE in * do echo $FILE done
遍历文件内容: city.txt
beijing
tianjin
shanghai
#!/bin/bash citys=`cat city.txt` #这里用到了变量存储 for city in $citys do echo $city done
输出:
beijing
tianjin
shanghai
4.while循环
while command
do
Statement(s) to be executed if command is true
done
示例:
#! /bin/bash c=0 while [ $c -lt 3 ] do echo "value is $c" c=$[ $c+1 ] done echo $c
输出:
value is 0 value is 1 value is 2 3
跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,像大多数编程语言一样,Shell也使用 break 和 continue 来跳出循环。
break
break命令允许跳出所有循环(终止执行后面的所有循环)。
#!/bin/bash i=0 while [ $i -lt 5 ] do i=`expr $i + 1` if [ $i == 3 ] then break fi echo -e $i done
运行结果:
1 2
在嵌套循环中,break 命令后面还可以跟一个整数,表示跳出第几层循环。例如:
break n
表示跳出第 n 层循环。
continue
continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
#!/bin/bash i=0 while [ $i -lt 5 ] do i=`expr $i + 1` if [ $i == 3 ] then continue fi echo -e $i done
运行结果:
1 2 4 5
八.读取控制台输入
read (选项)(参数) 选项: -p:指定读取指时提示符 -t:指定读取是的等待的时间(秒)如果没有在指定时间内输入我就不等待了 参数: 变量:指定读取的变量名
九.函数
1.系统函数
1. basename 文件名 返回完整路径/后面的文件,成用于获取文件名 如果再加上文件后缀,可以返回文件名
2. dirname 和上面相反,返回的是除文件名外的绝对路径
2.自定义函数
function function_name () { list of commands [ return value ] } #不需要形参,有点不习惯
其中function
关键字是可选的。
#!/bin/bash hello(){ echo 'hello'; } hello
调用函数只需要给出函数名,不需要加括号。
函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。
Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。如果 return 其他数据,比如一个字符串,往往会得到错误提示:numeric argument required
。
#!/bin/bash function hello(){ return 'hello'; } hello
运行结果:
line 4: return: hello: numeric argument required
如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。
#!/bin/bash function hello(){ return 'hello'; } str=hello echo $str
运行结果:
hello
像删除变量一样,删除函数也可以使用 unset
命令,不过要加上 .f
选项,如下所示:
$unset .f function_name
如果你希望直接从终端调用函数,可以将函数定义在主目录下的 .profile 文件,这样每次登录后,在命令提示符后面输入函数名字就可以立即调用。
函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n
的形式来获取参数的值,例如,$1
表示第一个参数,$2
表示第二个参数...这就是前面讲的特殊变量。
#!/bin/bash function sum(){ case $# in 0) echo "no param";; 1) echo $1;; 2) echo `expr $1 + $2`;; 3) echo `expr $1 + $2 + $3`;; *) echo "$# params! It's too much!";; esac } sum 1 3 5 6
运行结果:
4 params! It's too much!
注意,$10
不能获取第十个参数,获取第十个参数需要${10}
。当n>=10
时,需要使用${n}
来获取参数。
另外,还有几个特殊变量用来处理参数,前面已经提到:
特殊变量 说明 $# 传递给函数的参数个数。 $* 显示所有传递给函数的参数。 $@ 与$*相同,但是略有区别,请查看Shell特殊变量。 $? 函数的返回值。
如何获取函数返回值
后面的变量需要使用函数的返回值,怎么实现?
示例:
#!/bin/bash function sum() { echo `expr 1+2+3` } num=$(sum)
这样就可以取到返回值了。