shell脚本
shell是一个用C语言编写的程序,他是用户使用linux的桥梁,shell既是一种命令语言,又是一种程序设计语言。
shell脚本,是一种为shell编写的脚本程序,Linux的shell种类常见的有:
- Bourne Shell (/usr/bin/sh或/bin/sh)
- Bourne Again Shell (/bin/bash)
- C Shell (/usr/bin/csh)
- K Shell (/usr/bin/ksh)
…
常用的是bash,因为易用和免费。在使用bash执行脚本文件之前不需赋予脚本文件可执行权限,切换到脚本文件所在对应的目录执行"./脚本文件"表示执行当前目录下的脚本文件,或使用"bash 脚本文件"运行及哦啊本文件。
shell变量
shell变量命名规则:
- 只能使用英文字母,数字和下划线,输欧个字母不能以数字开头;
- 中间不能有空格,可以使用(_);
- 不能使用标点符号;
- 不能还用bash力的关键字;
- 变量名和等号之间不能有空格。
your_name=”tom“
echo $your_name ## 输出tom
echo ${your_name} ## 输出tom,花括号是为了确认变量边界
echo ${#your_name} ##输出9 获取字符串的长度
echo ${your_name:1:2} ## 输出om,从第二个字符开始截取连个字符
echo `expe index "$your_name" yo` ## 输出2,在变量your_name中查找y或者o,那个字母先出现计算那个
readonly your_name ## 设置只读变量,your_name变量将不可以被修改
unset your_name ## 删除变量your_name
strpingjie="hello,"$your_name"!"
strpingjie1="hello,${your_name} !" ##字符串拼接
array_name=(value1 value2 value3) 或者
array_name=(
value1
value2
value3
) 或者
array_name[0]=value1
array_name[1]=value2
array_name[2]=value3 ##定义数组
value=${array_name[1]} ##输出value2,获取到单个元素
echo ${array_name[@]}
echo ${array_name[*]} ##获取数组元素的个数
len=${#array_name[1]} ##获取单个元素的长度
:<<! 内容 ! 或者 :<<’ 内容 ‘ 等 ## 批量注释
vim test.sh
>#!/bin/bash
>echo "shell 传递的参数"
>echo "执行的文件名:$0";
>echo "第一个参数:$1";
>echo "第一个参数:$2";
>./test.sh 1 2
执行的文件名:./test.sh
第一个参数:1
第二个参数:2
参数 | 说明 |
---|---|
$0 | 执行的文件名称 |
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的左后一个进程的ID |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数 |
$- | 显示shell使用的当前选项,与set命令功能相等 |
$? | 显示最后命令的退出状态 |
shell运算符
原生bash是不支持简单的数学运算的,但是可以通过其他的命令来实现,例如awk和expr。表达式和运算符之间必须要有空格,完整的表达式必须要被``包含。
【1】算术运算符
运算符 | 说明 | 示例a=10, b=20 |
---|---|---|
+ | 加法 | expr $a + $b 结果为30 |
- | 减法 | expr $a - $b 结果为-10 |
* | 乘法 | expr $a \* $b 结果为200 |
/ | 除法 | expr $a / $b 结果为0.5 |
% | 取余 | expr $a % $b 结果为10 |
= | 赋值 | a=$b 将变量b的值赋给a |
== | 相等,用于比较两个数字,相同则返回true | [$a == $b] 返回false |
!= | 不相等,用于比较两个数字,不相同则返回true | [$a != $b]返回true |
【2】关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
运算符 | 说明 | 示例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 |
【3】布尔运算符
运算符 | 说明 | 示例a=10,b=20 |
---|---|---|
! | 非运算,表达式为true则返回false | [!false]返回true |
-o | 或运算,有一个表达式为true则返回true | [$a -lt $b -o $b -gt 100]返回true |
-a | 与运算,两个表达式都为 true 才返回 true | [$a -lt $b -o $b -gt 100]返回false |
【4】逻辑运算符
运算符 | 说明 | 示例a=10,b=20 |
---|---|---|
&& | 逻辑的AND | [[$a -lt $b && $b -gt 100]]返回false |
|| | 逻辑 OR | [[$a -lt $b || $b -gt 100]]返回true |
【5】字符串运算符
运算符 | 说明 | 示例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 |
printf 命令
经常使用的echo命令,主要是用于字符串的输出,printf命令模仿c程序库(library)里的print()程序,printf使用引用文本或空格分隔的参数,外面可以在printf中使用格式化字符串,还可以指定字符串的宽度,左右对齐方式等,默认printf不会像echo自动添加换行符,但printf的脚本比echo的移植性好。
printf命令语法:
printf format-string [arguments...]
【参数:
format-string : 为格式控制字符串
arguments : 为参数列表
】
>vim testp.sh
#!/bin/bash
printf "%-10s %-8s %-4s\n" 姓名 性别 身高
printf "%-10s %-8s %-4.2f\n" 张三 男 178.6633
printf "%-10s %-8s %-4.2f\n" 李四 男 169.5279
printf "%-10s %-8s %-4.2f\n" 王五 女 165.4565
>bsah testp.sh
>张三 男 178.66
李四 男 169.53
王五 女 165.46
%s %c %d %f都是格式替代符
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会显示在10个字符宽的字符内,如果不足则以空格填充,超过也会将内容泉币显示出来。
%-4.2f 指格式化为小数,其中.2表示保留2位小数,四舍五入。
序列 | 说明 |
---|---|
\a | 警告字符,通常为ASCII的BEL字符 |
\b | 后退 |
\c | 不显示输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 |
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ | 一个字面上的反斜杠字符 |
\ddd | 表示1到3位数八进制的字符,仅在格式字符串中有效 |
\0ddd | 表示1到3位的八进制值字符 |
## test检查某个条件是否成立
num1=60
num2=60
if test $[num1] -eq $[num2] ##[]表示基本的算术运算
then
echo "两个数相等"
else
echo "两个数不相等"
fi
输出:两个数相等
文件测试:
参数 | 说明 |
---|---|
-e 文件名 | 如果文件存在则为真 |
-r 文件名 | 如果文件存在且可读则为真 |
-w 文件名 | 如果文件存在且可写则为真 |
-x 文件名 | 如果文件存在且可执行为真 |
-s 文件名 | 如果文件存在且至少有一个字符则为真 |
-d 文件名 | 如果文件存在且为目录则为真 |
-f 文件名 | 如果文件存在且为普通文件则为真 |
-c 文件名 | 如果文件存在且为字符型特殊文件则为真 |
-b 文件名 | 如果文件存在且为块特殊文件则为真 |
cd /bin
if test -e ./bash
then
echo "文件已存在"
else
echo "文件不存在"
fi
流程控制
## if....elif....else
a=10
b=20
if [$a == $b]
then
echo "a等于b"
elif [$a -gt $b]
then
echo "a大于b"
elif [$a -lt $b]
then
echo "a小于b"
else
echo "没有符合的条件"
fi
输出:a小于b
## for 循环
for loop in 1 2 3 4 5
do
echo "the value is:$loop"
done
输出:
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
for str in 'this is a string'
do
echo $str
done
输出:This is a string
## while循环
vim testw.sh
#!/bin/bash
int=1
while(($int<=3))
do
echo $int
let "int++"
done
输出:1
2
3
## 跳出循环break
vim testt.sh
#!/bin/bash
while :
do
echo -n "输入1到5之间的数字:"
read anum
case $anum in
1|2|3|4|5) echo "你输入的数字为$anum"
;;
*) echo "你输入的数字不是1到5之间,游戏结束"
break
##cuntinue 继续执行
;;
esac
done
输出:
输入1到5之间的数字:4
你输入的数字为4
输入1到5之间的数字:8
你输入的数字不是1到5之间,游戏结束
case 中取值后面必须为单词in, 每一模式必须以右括号结束,取值可以为变量或常数,匹配发现取值复核某一模式后,其间所有命令开始执行直至;;
shell函数
linux shell中可以自定义函数,然后在shell脚本中随便调用。可以使用function fun()定义,也可以直接fun()定义。可以显示加 return 返回,如果不加,将以最后一条命令运行结束,作为返回值。
vim testh.sh
#!/bin/bash
function fun1(){
echo "hello world!"
}
fun1(){
echo "this is a rewrite"
}
fun2(){
echo "return 3"
return 3
echo "why?" ## return后边的内容将不会被执行
}
fun1
bash testh.sh
输出:this is a rewrite ,函数名相同以最后一个函数为准
fun2
bash testh.sh
输出return 3 并返回特定$?
echo $?
输出:3
fun2 1 2 3 4 ##给fun2传递参数
shell输入输出重定向
命令 | 说明 |
---|---|
command > file | 将输出重定向到file |
command < file | 将输入重定向到file |
command >> file | 将输出追加到file末尾 |
n > file | 将文件描述符为n的文件重定向到file |
n >> file | 将文件描述符为n的文件以追加的方式重定向到file |
n >& m | 将输出文件m和n合并 |
n <& m | 将输入文件m和n合并 |
<< tag | 将开始标记tag和结束标记tag之间的内容作为输入 |
如果将标准输出内容重定向到/dev/null文件,会起到禁止输出的效果,因为写入到/dev/null文件的内容都会被丢弃,如果尝试读取该文件的内容将啥也读不到。