1、shell : 操作linux的桥梁
(1)创建shell脚本:
后缀为 .sh 的文件 : vim helloworld.sh
(2)编写shell:
在头部写上注释 #!/bin/sh 或者 #!/bin/bash : 是一个标识 ,表示当前脚本(最好)用什么方式执行 , 是一个脚本
(#代表注释 此注释可写可不写,建议写上)
echo XXX : 输出XXX
echo -n xxx : -n 表示输出不换行,一般用在for循环里。
(3)运行shell:
1)通过sh命令执行
例如 : sh helloworld.sh
2)通过bash命令执行
例如 : bash helloworld.sh
3)通过把文件修改为可执行的文件(chmod 777 helloworld.sh) ,然后通过 ./ 命令.sh文件来执行
例如 : ./helloworld.sh(必须在当前目录下)
2、常量 : 在linux中,常量都是string类型 。 无论加""、''、不加。
3、变量 : 没有数据类型的限制,即不用对类型进行划分,但必须要初始化。
shell中没有声明,只有初始化。
(1)定义和初始化
变量名称=值
x=10 、 x=abc
注意:
等号两边不能有空格
shell中空格常做分隔符使用
(2)使用变量 : 通过 $
1)格式1:
$变量
$x
2)格式2:
${变量}
${x}
例 : 输出thisiszsis18
name=zs
echo "thisis${name}is18"
注意:
格式1,会把$后所有相连内容看做一个变量,如:echo "thisis$nameis18",会将$后面的nameis18全部作为一个变量。
格式2,${}表示值引用{}之中的内容,对相连的内容做了一个区分,相当于加一个边界。
没有变量不会报错,会输出一个空。
4、位置变量 : shell中自带的变量,等同于下标:0、1、2、3、4、5、6、7、8、9...
格式:
$下标
$0...$n : 表示接收外部参数(执行脚本时,传递的参数)
$* : 获取所有参数
$# : 获取所有参数个数
例 : echo 0
echo 1
echo 2
echo 4
echo $#
echo $* 保存退出
运行:sh test.sh 1 2 3 4 5
结果:test.sh
1
2
4
5
1 2 3 4 5
注意:
$0永远表示脚本名称(因为脚本名称不算数,所以$0不算做位置变量)
下标大于一位数只能使用${}获取参数,因为$下标只把第一位数据看做下标。
例:echo 10 保存退出
运行:sh test.sh a b c d e f g h i j
结果:a0 (想要的结果是:j)
错误原因:$10 --> $1 + 0 = a0
解决方法:${10} --> j
5、引号 : 所包裹的内容肯定是字符串。引号默认是连续成对出现的。
(1)单引号 : 按原字符串输出, 内容全部当作字符串使用。
(2)双引号 : 可以引用变量,拥有特殊含义的内容。
例: name=zs
echo "thisis$name"
echo 'thisis$name' 保存退出
结果:thisiszs
thisis$name
(3)转义符 : \ (只对双引号有用)
例:不加\:
echo zs:"18"
输出结果:zs:18
加上\: 相当于直接用单引号
echo zs:\"18\" (将双引号当做内容输出) --> echo 'zs:"18"'
输出结果:zs:"18"
(4)拼接 : 连续获取变量
注意:
如果有多个引号,连续的形成一对。
引号中使用其他引号,其他引号做字符串使用。
6、字符串 :
(1)获取长度:
${#变量名称}
例:str="abcdefg"
echo ${#str} --> 7
(2)截取 : 不会对原字符串进行修改,想要修改原字符串只能重新赋值。
${变量名称:开始位置:长度} \ ${name;offset;length}
例:str="abcdefg"
echo ${str:0:2} --> ab
注意:
${str::5} : 从0开始获取5个 --> abcde
${str:0} : 从0开始获取到末尾 --> abcdefg
(3)替换单个:
${变量/旧/新}
注意:
只替换从左向右出现的第一个匹配项。
(4)替换所有 : 替换从左向右出现的每一个匹配项。
${变量//旧/新}
注意:
替换不会在原字符上进行修改,想要修改原字符串只能重新赋值。
(5)删除 : 不会从中间删除。
1)从头开始删除:
${变量名#表达式} : 从头依次匹配,将匹配到的第一个删除
${变量名##表达式} : 从头依次匹配,将匹配到的最后一个删除
例:str="abc,def,g,abc"
echo ${str#def} --> abc,def,g,abc
echo ${str#abc} --> ,def,g,abc
echo ${str#*,} --> def,g,abc
echo ${str##*,} --> abc
2)从尾开始删除:
${变量名%表达式} : 从尾依次匹配,将匹配到的第一个删除
${变量名%%表达式} : 从尾依次匹配,将匹配到的最后一个删除
例:str="abc,def,g,abc"
echo ${str%def} --> abc,def,g,abc
echo ${str%abc} --> abc,def,g,
echo ${str%,*} --> abc,def,g
echo ${str%%,*} --> abc
注意:
删除不会在原字符上进行修改,想要修改原字符串只能重新赋值。
7、运算符 :
shell中默认不支持表达式(2+2、2-2、2*2、2/2等),因为shell中都是字符串。
shell提供了一个命令 :expr -- 可以识别表达式。
(1)算术运算符
bash不支持简单的数学运算,可以通过命令实现,如 : expr
格式1:
`expr 值 + 值`
例:x=2
y=3
echo `expr 2+2` --> 2+2
echo `expr 2 + 2` --> 4
echo `expr $x + $y` --> 5
echo `expr x + y` --> 语法错误
格式2: (常用)
$[值+值]
$[变量+变量] #变量可以不加$
例:x=2
y=3
echo $[2+2] --> 5
echo $[$x+$y] --> 5
echo $[${x}+${y}] --> 5
echo $[x+y] --> 5
注意:
格式1:符号两边需要加上空格 。
格式2:不需要考虑空格、反引号等问题,$[]可以自动识别变量。以后直接用。
(2)比较运算符: > 、< 、>= 、<= ....
格式:
$[值 比较符号 值] (比较符号两边空格加不加无所谓,$[]可以自动识别)
例:echo $[2>1] --> 1
echo $[3>4] --> 0
注意:
比较的结果用1(true)和0(false)表示
(3)逻辑运算符:
1)&/and : 两边都成立才成立
2)|/or : 两边都不成立才不成立
3)!/not : 取反
例如:
echo $[2>1 & 2<1] --> 0
echo $[2>1 | 2<1] --> 1
echo $[!1&0] --> $[0&0]=0
echo $[!(1&0)] --> $[!0]=1
8、shell 程序流程控制:
if
格式1:
if 判断条件 ( 判断条件最好使用(()) )
then
判断为true执行的代码
fi
格式2:
if 判断条件
then
判断为true执行的代码
else
判断为false执行的代码
fi
或:
if 判断条件
then
判断为true执行的代码
if 判断条件
then
判断为true执行的代码
else
判断为false执行的代码
fi
else
判断为false执行的代码
fi
格式3:
if 判断条件
then
判断为true执行的代码
elif 判断条件
then
判断为true执行的代码
...
else
判断为false执行的代码
fi
注意:
else可加可不加
判断条件的写法:
1) [] : 每一部分内容都以空格分割,默认不能识别比较符号(>、<),可以使用转义符但比较符号两边数值不能超过两位数,且不能多个比较符号(>=、<=)。也可以使用字母 -gt、-lt 代替。
适用于以字母表示判断条件。
例:if [ 30 > 12 ] --> 错误
if [ 30 \> 12 ] --> 正确
if [ 99 \> 120 ] --> 错误
if [ 99 \>= 12 ] --> 错误
if [ 30 -gt 120 ] --> 正确
2) [[]] : 每一部分内容都以空格分割,可以识别比较符号(>、<)但比较符号两边数值不能超过两位数 ,不能识别多个比较符号(>=、<=) ,也可以使用字母 -ge 、 -le 代替。在使用变量时 ,可以不使用$。
使用中括号时,直接使用字母进行判断,不需要考虑注意事项。
若使用比较符号,需要考虑的注意事项比较多。
例:if [[ 30 > 12 ]] --> 正确
if [[ 99 > 120 ]] --> 错误
if [[ 99 >= 12 ]] --> 错误
if [[ 30 -ge 120 ]] --> 正确
age=20
if [[ $age -ge 18 ]] --> 正确
if [[ age -ge 18 ]] --> 也正确
3) () : 弃用
4) (()) : 不需要考虑空格问题 ,可以无条件使用单个、多个符号 ,也不需要考虑数值是否大于两位数问题 。但是不能使用字母 。在使用变量时 ,可以不使用$。
例:if ((30>120)) --> 正确
if ((30>=120)) --> 正确
age=20
if (($age>18)) --> 正确
if ((age>18)) --> 也正确
字母:
-eq : 检测两个数是否相等,相等返回true
-ne : 检测是否不相等,不相等返回true
-gt : 检测是否大于,如果是返回true
-lt : 检测是否小于,如果是返回true
-ge : 检测是否大于等于,如果是返回true
-le : 检测是否小于等于,如果是返回true
判断字符串 :
sex="女"
if ((sex==男)) --> 错误
if ((sex=="男")) --> 错误
if [[ sex -eq 男 ]] --> 错误
if [[ $sex == 男 ]] --> 正确
9、for循环
循环是解决连续多次相同代码、连续有规律的代码的问题。
(1)类似java格式:
for ((初始化变量;判断条件;控制语句))
do
执行语句
done
for ((i=1;i<=10;i++))
可以写成:
for ((i=1;i<=10;i=i+1))
for ((i=1;i<=10;i*=2)) (i=i*2 -> i*=2)
例:打印9-9乘法表
for((i=1;i<=9;i++))
do
for((j=1;j<=i;j++))
do
echo -n "$j*$i=$[i*j] " #-n 表示输出不换行 ,双引号后面与内容空一格表示每打印一个,中间隔一个。
done
echo "" #跳到下一行
done
(2)类似迭代器格式 增强for:
for 变量 in 结果集
do
执行语句
done
结果集格式:
1) {开始..结束} : 含头含尾。 可以引用变量,但不会产生结果集,而是将其当做一个整体。
例:输出1~100
for x in {1..100}
do
echo $x
done
2) `seq 开始 结束` : 含头含尾。 可以引用变量产生结果集。
例1:输出1~100
for x in `seq 1 100`
do
echo $x
done
例1:输出1~100的和
sum=0
for x in `seq 1 100`
do
sum=$[sum+x]
done
echo $sum
例2: 获取1-100的奇数和偶数和
jsum=0
osum=0
for i in {1..100}
do
if ((${i}%2==0))
then
#osum=osum+${i} #结果当成字符串拼接 ,不是算术运算。
osum=$[osum+i]
#let osum+=$i #let 也可以识别算术运算。
else
let jsum+=$i
fi
done
echo 偶数和为:${osum}
echo 奇数和为:${jsum}
注意:
使用let在计算时可以直接使用变量。
例3:打印9-9乘法表
for i in `seq 1 9`
do
for j in `seq 1 $i`
do
echo -n "$j*$i=$[i*j] " #-n 表示输出不换行 ,双引号后面与内容空一格表示每打印一个,中间隔一个。
done
echo "" #跳到下一行
done
例4:判断一个数是不是素数(素数:除了1和本身没有其他的因数)
x=13
flag=1 #假设是素数
for i in `seq 2 $[x-1]` #除以2 ~ 本身-1
do
if ((x%i==0)) #用来验证
then
flag=0 #若x被i整除,说明不是素数
break
fi
done
if((flag==1))
then
echo $x是素数
else
echo $x不是素数
fi
例5、判断1~100之间的数是不是素数
for x in `seq 1 100`
do
flag=1
for i in `seq 2 $[x-1]`
do
if((x%i==0))
then
flag=0
break
fi
done
if((flag==1))
then
echo $x是素数
else
echo $x不是素数
fi
done
10、数组:存储多个元素,数据类型可以不同,元素元素之间以空格切分
操作
通过下标获取数据
格式:
${数组[下标]}
注意:
直接引用数组变量,默认获取下标为0的元素
下标使用*表示获取所有
获取长度:
格式:
${#数组[*]}
read:键盘录入
格式:
read 变量1 变量2 ...变量n
注意:
键盘录入时,允许给多个变量进行赋值,值和值之间以空格切分
函数
格式:
function 方法名(){
方法体
return 数字;
}
注意:function和return可加可不加
$0...$n表示接收参数,$0永远是脚本名称(忽略)
方法的调用直接使用方法名不加()
return只能返回数字范围在0-255之间
$?接收返回值只能接收一次
获取当前日期时间
ate +"%Y-%m-%d %H:%M:%S"
格式化日期时间:
date -d today +"%Y-%m-%d %H:%M:%S"
加减日期时间
date +%Y%m%d //显示前天年月日
date +%Y%m%d --date="+1 day" //显示前一天的日期
date +%Y%m%d --date="-1 day" //显示后一天的日期
date +%Y%m%d --date="-1 month" //显示上一月的日期
date +%Y%m%d --date="+1 month" //显示下一月的日期
date +%Y%m%d --date="-1 year" //显示前一年的日期
date +%Y%m%d --date="+1 year" //显示下一年的日期
重定向:执行命令的结果写写入到文件
标准输入文件(stdin):stdin的文件描述符为0,默认从stdin读取数据。
标准输出文件(stdout):stdout 的文件描述符为1,默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,向stderr流中写入错误信息。
使用>,>>默认是把正确信息写入文件
想要把错误信息和正确信息写入文件需要后面追加2>&1(把错误信息当做正确信息去处理)
定时器:
格式:
*(分钟) *(小时) *(星期) *(几号) *(月份) commend
通过crontab -e添加定时任务
查看定时任务是否执行了,看日志tail -f /var/log/cron
注意:
定时器或脚本中涉及到路劲的全部给绝对路劲
* * * * * 每分钟
*/1 * * * * 每分钟
0 */1 * * * 每小时