linux 提供的Shell 解析器有很多,最常用的俩个解析器为:sh和bash。
Centos默认的解析器是bash
[root@zjh home]# echo $SHELL
/bin/bash
脚本格式
脚本以#!/bin/bash 开头(指定解析器)
第一个Shell 脚本:helloworld
# 创建脚本
[root@zjh home]# cat helloworld.sh
#!/bin/bash
echo "hello zjh"
# 执行脚本方式1
[root@zjh home]# bash helloworld.sh
hello zjh
# 执行脚本方式2
[root@zjh home]# ./helloworld.sh
-bash: ./helloworld.sh: 权限不够
方式1,本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限;
方式2,本质是脚本自己需要执行,所以需要执行权限
第二个Shell 脚本:多命令处理
需求 :在linux家目录下创建一个bangzhang.txt并在文件中写入"I IOVE YOU"字符.
[root@zjh home]# touch batch.sh
[root@zjh home]# vim batch.sh
#!/bin/bash
cd /home/linux/
touch banzhang.txt
echo "I LOVE YOU" >> banzhang.txt
常用系统变量 $HOME $PWD $SHELL $USER
[root@zjh home]# echo $HOME
/home/linux
[root@zjh home]# echo $PWD
/home/linux/datas
[root@zjh home]# echo $SHELL
/bin/bash
[root@zjh home]# echo $USER
linux
1.基本语法
定义变量:变量=值 等号两边不能留有空格
撤销变量:unset 变量
输出变量:echo $变量
声明静态变量: readonly 变量,注意:不能unset
[root@zjh home]# A=1
[root@zjh home]# echo $A
1
[root@zjh home]# unset A
# readonly 变量,注意:不能unset
[root@zjh home]# readonly B=2
[root@zjh home]# echo $B
2
[root@zjh home]# B=9
-bash : B: readonly variable
2.变量定义规则
变量名称可以由字母,数字和下划线组成,不能以数字开头,环境变量名建议大写
等号两侧不能有空格
在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
变量的值如果有空格,需要使用双引号或单引号括起来
[root@zjh home]# D="A B C"
[root@zjh home]# echo $D
A B C
[root@zjh home]# C=1+2
[root@zjh home]# echo $c
1+2
#!/bin/bash
echo "$0" "$1" "$2" "$3"
[root@zjh home]# sh parameter.sh
parameter.sh
[root@zjh home]# sh parameter.sh 10 lal 20
parameter.sh 10 lal 20
####4.4 特殊变量:$#
[root@zjh home]# vim parameter.sh
#!/bin/bash
echo "$0" "$1" "$2"
echo $#
[root@zjh home]# bash parameter.sh
parameter.sh
0
[root@zjh home]# bash parameter.sh 10 lala 20
parameter.sh 10 lala 20
3
####4.5 特殊变量: ∗ 和 * 和 ∗和@
$* ——代表命令行中所有的参数,把所有参数看成一个整体
$@ ——也代表命令行中所有的参数,不过把每个参数区分对待
[root@zjh home]# vim parameter.sh
echo "$0" "$1" "$2" "$3"
echo $#
echo $*
echo #@
[root@zjh home]# sh parameter.sh 1 2 3
parameter.sh 1 2 3
3
1 2 3
1 2 3
$?——最后一个执行的命令的返回状态。如果这个变量的值为0,则最后一个命令正确执行
如果这个值为非0(具体哪一个数,由命令自己来决定),则证明上一个命令执行不正确
[root@zjh home]# sh parameter.sh 1 2 3
parameter.sh 1 2 3
3
1 2 3
1 2 3
[root@zjh home]# $? 执行失败返回非0
-bash:0 : command not found
[root@zjh home]# echo $?
127
[root@zjh home]# sh parameter.sh 1 2 3 执行成功返回0
parameter.sh 1 2 3
3
1 2 3
1 2 3
[root@zjh home]# echo $?
0
计算3+2的值
[root@zjh home]# expr 2 + 3
5
[root@zjh home]# expr 2+3
error
计算(2+3)x4的值
[root@zjh home]# expr `expr 2 + 3` \* 4
20
[root@zjh home]# a=$[(2+3)*4]
[root@zjh home]# echo $a
20
[ condition ] (注意 condition前后要有空格)
注意:条件非空即为true, [atguigu] 返回 true, []返回false
符号 | 描述 |
---|---|
-lt | (less than) 小于 |
-le | (less equal) 小于等于 |
-eq | (equal) 等于 |
-gt | (greater than) 大于 |
-ge | (greater equal) 大于等于 |
-ne | (no eqeual) 不等于 |
# 判断23是否大于2
[root@zjh home]# $ [ 23 -gt 2 ]
[root@zjh home]# echo $?
0
[root@zjh home]# $ [ 23 -le 2 ]
[root@zjh home]# echo $? #返回值非0说明上一条指令执行错误,也就是[ 23 -le 2 ]
1 #是错误的
# 判断helloworld.sh是否有写入权限
[root@zjh home]# [ -w hellowrld.sh ]
[root@zjh home]# echo $?
0
# 判断目录中文件是否存在
[root@zjh home]# [ -e /home/linux/datas ]
[root@zjh home]# echo $?
0
#多条件判断
[root@zjh home]# [ condition ] && echo OK || echo notok
OK
[root@zjh home]# [ condition ] && [] || echo notol
notok
注意事项:[ 条件判断 ],中括号和条件判断之间必须有空格。
if 后要有空格
[root@zjh home]# cat if.sh
#!/bin/bash
if [ $1 -eq 1 ]
then
echo "我最帅"
elif [ $1 -eq 2 ]
then
echo "我最好看"
fi
[root@zjh home]# bash if.sh 2
我最好看
注意事项:
[root@zjh home]# cat case.sh
#!/bin/bash
case $1 in
1)
echo "班长"
;;
2)
echo "学委"
;;
3)
echo "体委"
;;
*)
exho "人妖"
esac
[root@zjh home]# bash case.sh 4
人妖
[root@zjh home]# cat for.sh
#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
s=$[$s+$i]
done
echo $s
[root@zjh home]# bash for.sh
5050
[root@zjh home]# cat for2.sh
#!/bin/bash
for i in $*
do
echo $i
done
for i in $@
do
echo $j
done
[root@zjh home]# bash for2.sh 1 2 //看不出什么区别
1
2
1
2
[root@zjh home]# cat for2.sh
#!/bin/bash
for i in "$*"
do
echo $i
done
for i in "$@"
do
echo $j
done
[root@zjh home]# bash for2.sh 1 2 //能看出明显区别
1 2 //$* 是把输入的看成一个整体全部赋给i
1 //$@ 是把输入分开传送,依次循环赋给j
2
[root@zjh home]# cat while.sh
#!/bin/bash
s=0
i=1
while [ $i -le 100 ] //i是变量,我们这里使用的是i的值i的值为$i
do
s=$[$s + $i]
i=$[$i + 1]
done
echo $s
[root@zjh home]# bash while.sh
5050
read(选项)(参数)
参数:
变量:指定读取值得变量名
实际上就是把选项输入的值,赋给变量(参数)
# 提示7秒内,读取控制台输入的名称
[root@zjh home]# cat read.sh
#!/bin/bash
read -t 7 -p "input your name" NAME
echo $NAME
[root@zjh home]# bash read.sh //如果7秒没有输入自动结束
[root@zjh home]# bash read.sh
input your name zjh
zjh
basename 基本语法
basename[string / pathname] [suffix] ——basename命令会删掉所有的前缀包括最后一个(’/’)字符,然后将字符串显示出来。
选项:
suffix 为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉
# 方式1
[root@zjh home]# basename /home/linux/banzhang.txt
banzhang.txt
# 方式2
[root@zjh home]# basename /home/linux/banzhang.txt .txt
banzhang
dirname基本语法
dirname 文件绝对路径——从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
[root@zjh home]# dirname /home/linux/banzhang.txt
/home/linux
#格式
[function] funname[()] //[function] 选择项可写,可不写
{
Action;
[return int;]
}
funname
经验技巧
必须在调用函数之前,先声明函数,shell脚本是逐步运行。不会像其他语言一样先编译。
函数返回值,只能通过$?系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255).
# DESC 计算输入两个参数的值
[root@zjh home]# cat sum.sh
#!/bin/bash
function sum(){
s=0;
s=$[$1 + $2]
echo $s
}
read -p "input your sum1:" P1
read -p "input your sum2:" P2
sum $P1 $P2
[root@zjh home]# bash sum.sh
input your sum1:1
input your sum2:2
3
cut命令从文件的每一行剪切字节,字符和字段并将这些字节,字符和字段输出。
cut [选项参数] filename
说明:默认分隔符是制表符
# DESC 切割cut.txt第一列
[root@zjh home]# cat cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
[root@zjh home]#cut -d " " -f 1 cut.txt
dong
guan
wo
lai
le
#在cut.txt文件中切割出guan
[root@zjh home]# cat cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
[root@zjh home]# cat cut.txt | grep guan
guan zhen
[root@zjh home]# cat cut.txt | grep guan | cut -d " " -f 1
guan
#选取系统PATH变量值,第2个“:”开始后的所有路径
[root@zjh home]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/
usr/sbin:/sbin:/home/atguigu/bin
[root@zjh home]# echo $PATH | cut -d : -f 3- //不加-表示第三列,加=表示第三列之后
/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/atguigu/bin
#切割ifconfig后打印IP地址
[root@zjh ~]# ifconfig ens33
ens33: flags=4163 mtu 1500
inet:192.168.56.137 netmask:255.255.255.0 broadcast:192.168.56.255
inet6 fe80::5da3:53d8:5d87:598c prefixlen 64 scopeid 0x20
ether 00:0c:29:ad:3d:0f txqueuelen 1000 (Ethernet)
RX packets 1818 bytes 139153 (135.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 301 bytes 28358 (27.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@zjh ~]# ifconfig ens33 | grep inet
inet:192.168.56.137 netmask:255.255.255.0 broadcast:192.168.56.255
[root@zjh ~]# ifconfig ens33 | grep inet | cut -d : -f 2
192.168.56.137 netmask
[root@zjh ~]# ifconfig ens33 | grep inet | cut -d : -f 2 | cut -d " " -f 1
192.168.56.137
####10.2 sed
1. 基本用法
2.选项参数说明
sed [选项参数] ‘command’ filename
3. 命令功能描述
a 新增,a的后面可以接字符串,在下一行出现
d 删除
s 查找并替换
# DESC 在第二行后增加mei nv字符
[root@zjh ~]# sed "2a mei nv" sed.txt //2a表示第二行
dong zhen //单个一个需求命令的话,不需要-e,后面再说
guan zhen
mei nv
wo wo
lai lai
#删除set.txt文件所有包含wo的行
[root@zjh ~]# sed '/wo/d' sed.txt
dong zhen
guan zhen
lai lai
#将sed.txt文件中wo替换为ni
[root@zjh ~]# sed "s/wo/ni/g" sed.txt g代表全局变量,把所有的wo替换为ni
dong zhen
guan zhen
ni ni
lai lai
#将sed.txt文件中的第二行删除并将wo替换成ni
[root@zjh ~]# sed -e "2d" -e "s/wo/ni/g" sed.txt
dong zhen
ni ni
lai lai
awk 一个强大文件分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
awk [选项参数] 'pattern1 {action1} pattern2{action2}..' filename
sort 命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出
sort [选项] (参数)
参数 | 描述 |
---|---|
-n | 依照数值大小排序 |
-r | 以相反的顺序排序 |
-t | 设置排序时使用的分隔字符 |
-k | 指定需要排序的列 |
hen
lai lai
```c++
#将sed.txt文件中wo替换为ni
[root@zjh ~]# sed "s/wo/ni/g" sed.txt g代表全局变量,把所有的wo替换为ni
dong zhen
guan zhen
ni ni
lai lai
#将sed.txt文件中的第二行删除并将wo替换成ni
[root@zjh ~]# sed -e "2d" -e "s/wo/ni/g" sed.txt
dong zhen
ni ni
lai lai
awk 一个强大文件分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
awk [选项参数] 'pattern1 {action1} pattern2{action2}..' filename
sort 命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出
sort [选项] (参数)
参数 | 描述 |
---|---|
-n | 依照数值大小排序 |
-r | 以相反的顺序排序 |
-t | 设置排序时使用的分隔字符 |
-k | 指定需要排序的列 |