菜单
一、常用的Shell解析器
[root@rancher bin]# cd /bin
[root@rancher bin]# ll | grep bash
-rwxr-xr-x. 1 root root 964536 Apr 1 2020 bash
lrwxrwxrwx. 1 root root 10 Aug 7 2021 bashbug -> bashbug-64
-rwxr-xr-x. 1 root root 6964 Apr 1 2020 bashbug-64
lrwxrwxrwx. 1 root root 4 Aug 7 2021 sh -> bash
从结果不难看出,Shell的两个解析器sh和bash,其中sh是bash的软链接
1.1 查看系统默认的解析器
[root@rancher bin]# echo $SHELL
/bin/bash
1.2 编写简单的脚本
[root@rancher test]# vim hello.sh
[root@rancher test]# cat hello.sh
#!/bin/bash
echo "hello word"
[root@rancher test]# bash hello.sh
hello word
[root@rancher test]# sh hello.sh
hello word
[root@rancher test]# bash /data/app/test/hello.sh
hello word
[root@rancher test]# bash ./hello.sh
hello word
[root@rancher test]# sh ./hello.sh
hello word
1.3 脚本执行命令
目的:在/data/app/test目录下,创建一个fox.txt文件,并添加内容”hello word”
[root@rancher test]# vim create_fox.sh
[root@rancher test]# cat create_fox.sh
#!/bin/bash
cd /data/app/test
touch fox.txt
echo "hello world" >> fox.txt
cat /data/app/test/fox.txt
[root@rancher test]# bash create_fox.sh
hello world
二、Shell的变量
2.1Linux常用变量
- HOME 家目录
- PWD 当前目录
- SHELL 默认的bash解析器
- USER 当前用户
[root@rancher test]# vim variable.sh
[root@rancher test]# cat variable.sh
#!/bin/bash
echo "Home $HOME"
echo "PWD $PWD"
echo "SHELL $SHELL"
echo "USER $USER"
[root@rancher test]# bash variable.sh
Home /root
PWD /data/app/test
SHELL /bin/bash
USER root
2.2linux定义变量
注意: 等号两侧不能有空格, 如果变量有空格,用双引号括起来
----定义变量
[root@rancher test]# A=123
[root@rancher test]# echo $A
123
----撤销变量
[root@rancher test]# unset A
[root@rancher test]# echo $A
---设置变量只读,该变量不能撤销
[root@rancher test]# readonly B=3
[root@rancher test]# unset B
-bash: unset: B: cannot unset: readonly variable
该变量重启后将不复存在
2.3设置环境变量
----临时环境变量,换窗口,重启,不同用户都不行
[root@rancher test]# export TEST_HOME=/data/app/test/
[root@rancher test]# echo $TEST_HOME
----设置环境变量
[root@rancher test]# vim /etc/profile
###追加
#TEST Dir
export TEST_HOME=/data/app/test
[root@rancher test]# source /etc/profile
[root@rancher test]# echo $TEST_HOME
/data/app/test
2.4 脚本读取变量
$n:n为数字,$0 代表该脚本名称,$1-$9 代表第一到第九个参数,十以上的参数需要用大括号包含${10}
[root@rancher test]# cat demo3.sh
#!/bin/bash
echo "$0 $1 $2 $3 $4"
[root@rancher test]# bash demo3.sh my fox say hello
demo3.sh my fox say hello
[root@rancher test]#
2.5 $# 获取所有输入参数的个数,多用于循环
[root@rancher test]# cat demo4.sh
#!/bin/bash
echo "$0 $1 $2 $3 $4"
echo $#
[root@rancher test]# bash demo4.sh my fox say hello
demo4.sh my fox say hello
4
2.6 $* 代表命令行中所有参数,把所有参数看成一个整体
2.7 $@:代表命令行中所有的参数,不过把每个参数区分对待
[root@rancher test]# cat demo5.sh
#!/bin/bash
echo "$0 $1 $2 $3 $4"
echo "$*" $*
echo "$@" $@
[root@rancher test]#
[root@rancher test]# bash demo5.sh my fox say hello
demo5.sh my fox say hello
my fox say hello my fox say hello
my fox say hello my fox say hello
[root@rancher test]#
2.8 $?:最后一次执行命令的返回状态
如果变量的数值为0,则表示正确执行,非0代表上一个命令执行不成功。
[root@rancher test]# echo 1
1
[root@rancher test]# echo $?
0
[root@rancher test]# cp demo4.sh demo4.sh
cp: ‘demo4.sh’ and ‘demo4.sh’ are the same file
[root@rancher test]#
[root@rancher test]# echo $?
1
三、运算符
基本语法
- $((运算式))
- $[运算式]
- expr +,-,*,/,% (注意:expr运算符间要有空格)
[root@rancher ~]# echo $[(3+2)*2]
10
[root@rancher ~]#
[root@rancher ~]# echo $(((3+2)*2))
10
[root@rancher ~]# expr substr "hello my_fox" 7 6
my_fox
###expr运算符间要有空格
[root@rancher ~]# expr 3 + 2
5
四、条件判断
基本语法[ condition ] condition前后要后空格
4.1常用的条件判断
- = 字符串比较
- -lt 小于
- -le 小于等于
- -eq 等于
- -gt 大于
- -ge 大于等于
- -ne 不等于
[root@rancher ~]# [ 23 -le 22 ]
[root@rancher ~]# echo $?
1
[root@rancher ~]# [ "hello" = "fox" ]
[root@rancher ~]# echo $?
1
[root@rancher ~]#
[root@rancher ~]# [ "hello" = "hello" ]
[root@rancher ~]# echo $?
0
4.2 文件权限判断
- -r 有读的权限
- -w 有写的权限
- -e 文件存在
- -d 存在文件并且是一个目录
[root@rancher test]# [ -w hello.sh ]
[root@rancher test]# echo $?
0
[root@rancher test]# [ -e /data/app/test/app.logs ]
[root@rancher test]# echo $?
1
4.3 多条件判断
&&:前一条命令执行成功时,才执行后一条命令
||:表示上一条命令执行失败后,才执行下一条命令
[root@rancher test]# [ condition ] && echo ok || echo notok
ok
[root@rancher test]# [ condition ] && [ ] || echo notok
notok
4.4 IF判断
4.4.1 模式1
if [ 条件判断 ];then
程序
fi
4.4.2 模式2
if[ 条件判断 ]
then
程序
fi
4.4.3 IF的demo
如果输入1,则输出hello,输入2则输出fox。
主题if后面要有空格,中括号两边也要有空格
[root@rancher test]# cat if.sh
#!/bin/bash
if [ $1 -eq 1 ];then
echo "hello"
elif [ $1 -eq 2 ];then
echo "fox"
fi
[root@rancher test]# bash if.sh 1
hello
[root@rancher test]# bash if.sh 2
fox
4.5 case
4.5.1 语法
case $变量名 in
"value1")
当变量等于value1时,执行程序1
;;
"value2"
当变量等于value2时,执行程序2
;;
*)
变量都不是以上的值,执行
;;
esac
4.5.2 case-demo
如果输入b,则输出boy;输入g,则输出girl;其他则输出fox
[root@rancher test]# cat case.sh
#!/bin/bash
case $1 in
"b")
echo "boy"
;;
"g")
echo "girl"
;;
*)
echo "fox"
;;
esac
[root@rancher test]# bash case.sh g
girl
[root@rancher test]# bash case.sh b
boy
[root@rancher test]# bash case.sh
fox
4.6 for循环
4.6.1语法一
for(( 初始值;循环控制条件;变量变化))
do
程序
done
例子: 从1~100进行累加
[root@rancher test]# cat for.sh
#!/bin/bash
s=0
for((i=i;i<=100;i++))
do
s=$[$s + $i]
done
echo $s
[root@rancher test]# bash for.sh
5050
4.6.2语法二
for 变量 in 值1 值2 值3 值4
do
程序
done
通过for案例了解$*和$@的区别
[root@rancher test]# cat for2.sh
#!/bin/bash
for i in $*
do
echo "*:Enter keyword $i"
done
for j in $@
do
echo "@:Enter keyword $j"
done
[root@rancher test]# cat for3.sh
#!/bin/bash
for i in "$*"
do
echo "*:Enter keyword $i"
done
for j in "$@"
do
echo "@:Enter keyword $j"
done
[root@rancher test]# bash for2.sh a b c d
*:Enter keyword a
*:Enter keyword b
*:Enter keyword c
*:Enter keyword d
@:Enter keyword a
@:Enter keyword b
@:Enter keyword c
@:Enter keyword d
[root@rancher test]# bash for3.sh a b c d
*:Enter keyword a b c d
@:Enter keyword a
@:Enter keyword b
@:Enter keyword c
@:Enter keyword d
通过案例,我们最后得出$*加上双引号会成为一个整体
4.7while循环
4.7.1 语法
while [ 条件判断 ]
do
程序
done
4.7.2 例子从1加到100
[root@rancher test]# cat while.sh
#!/bin/bash
s=0
i=0
while [ $i -le 100 ]
do
s=$[$s + $i]
i=$[$i + 1]
done
echo "i:$i"
echo "s:$s"
[root@rancher test]# bash while.sh
i:101
s:5050
4.8 read 读取控制台输入
4.8.1基本语法
read (选项)(参数)
选项:
- -p:指定读取值时的提示符
- -t:指定读取值时等待的时间
参数:
- -p:指定读取值时的提示符
4.8.2 案例:提示7秒内,读取控制台输入的名称
[root@rancher test]# cat read.sh
#!/bin/bash
read -t 7 -p "Enter you name in 7 second: " NAME
read -t 7 -p "Enter you password in 7 sencond: " PASSWORD
echo "UserName: $NAME,PassWord: $PASSWORD"
[root@rancher test]# bash read.sh
Enter you name in 7 second: My_fox
Enter you password in 7 sencond: Fox_password
UserName: My_fox,PassWord: Fox_password
五、函数
5.1 系统函数
5.1.1 basename输出文件名
删除所有前缀包括最后一个“/”然后将字符串显示出来(即输出文件名)
[root@rancher test]# basename hello.sh
hello.sh
[root@rancher test]# basename /data/app/test/hello.sh
hello.sh
[root@rancher test]# basename hello.sh .sh
hello
5.1.2 dirname 文件绝对路径,获得文件的目录
[root@rancher test]# dirname hello.sh
.
[root@rancher test]# dirname /data/app/test/hello.sh
/data/app/test
5.2 自定义函数
5.2.1 语法
return:如果不加,将最后一条命令运行结果,作为返回值。return后跟数据n(0-255)
function funname ()
{
//Action
//return 2;或者 echo $?
}
5.2.2 例子控制台输入的两个数字求和
[root@rancher test]# cat customefun.sh
#!/bin/bash
function sum()
{
s=0
s=$[$1 + $2]
echo $s
}
read -p "Enter your paratemer1: " p1
read -p "Enter your paratemer2 " p2
sum $p1 $p2
[root@rancher test]# bash customefun.sh
Enter your paratemer1: 4
Enter your paratemer2 7
11
六、CUT 负责剪切数据
6.1 基本语法
cut [选项参数] filename
选项参数
- -f 列号
- -d 分隔符
6.2 准备一个文件
[root@rancher test]# cat cut.txt
dong shen guang
guan zhen dong
wo wo
lai lai
le le
6.3 例子1获得第一列内容
[root@rancher test]# cut -d " " -f 1 cut.txt
dong
guan
wo
lai
le
6.4 切割获得第2,3列
[root@rancher test]# cut -d " " -f 2,3 cut.txt
shen guang
zhen
wo
lai
le
6.5 切割获取第2列之前-2和第2列之后2-
[root@rancher test]# cat cut.txt
dong shen guang
guan zhen dong
wo wo
lai lai
le le
[root@rancher test]# cut -d " " -f -2 cut.txt
dong shen
guan
wo
lai
le le
[root@rancher test]# cut -d " " -f 2- cut.txt
shen guang
zhen dong
wo
lai
le
6.6: 选取环境变量第二个:后面的
[root@rancher test]# echo $PATH | cut -d ":" -f 3-
/usr/sbin:/usr/bin:/data/app/jdk/bin:/data/app/rocketmq/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/data/app/jdk/bin:/root/bin
七、sed 流编辑器
sed是一种流编辑器,它一次处理一行内容。文件内容并没有改变,除非你使用重定向存储输出
sed [选项参数] ‘commad’ filename
选项
- -e 直接在指令列模式上进行sed的动作编辑
命令功能
- a:新增,a后面可以接字串,在下一行出现
- d:删除
- s:查看并替换
- i:修改源文件
7.1 数据准备
[root@rancher test]# cat sed.txt
dong shen guang
guan zhen dong
wo wo
lai lai
le le
7.2 例子将“my fox”这个字符串插入到sed.txt第三行下面
###加入-i 后会更改文件
[root@rancher test]# sed -i '3a my fox so handsome' sed.txt
dong shen guang
guan zhen dong
wo wo
my fox so handsome
lai lai
le le
7.3 删除sed.txt文件所包含wo行
[root@rancher test]# sed '/wo/d' sed.txt
dong shen guang
guan zhen dong
my fox so handsome
lai lai
le le
7.4 将sed.txt文件中的第二行删除并将wo替换成ni
[root@rancher test]#
[root@rancher test]# cat sed.txt
dong shen guang
guan zhen dong
wo wo
my fox so handsome
lai lai
le le
[root@rancher test]# sed -e '2d' -e 's/wo/ni/g' sed.txt
dong shen guang
ni ni
my fox so handsome
lai lai
le le
八:awk 强大的文本分析工具
默认以空格作为分隔符将每行切片,切开不分再进行分析处理
8.1 awk的基本语法
awk [选项参数] ‘pattern1{action1} pattern2{action2}…’ filename
pattern:表示AWK在数据中查找内容,就是匹配模式
action
- i:找到匹配内容时所执行的一系列命令
- -F 指定输入文件的分隔符
- -v 赋值给一个用户定义变量
8.2 搜索passwd文件以root关键字开头的所有行,并输出改行的第7列
[root@rancher test]# sudo cp /etc/passwd /data/app/test
[root@rancher test]# awk -F: '/^root/{print "$7}' /data/app/test/passwd
root /bin/bash
8.3 搜索passwd文件以root关键字开头的所有行,并输出该行的第1和第7列,中间用”,”分割
[root@rancher test]# awk -F: '/^root/{print $1","$7}' /data/app/test/passwd
root,/bin/bash
8.4 只显示passwd的第一列和第七列,以逗号分割,且在所有行前面添加列 ‘user,shell’,在最后一行添加 “fox,bin/fox”
[root@rancher test]# awk -F: 'BEGIN{print "user/shell"}{print $1"/"$7}END{print "fox/bin/fox"}' /data/app/test/passwd
user/shell
root//bin/bash
bin//sbin/nologin
daemon//sbin/nologin
adm//sbin/nologin
lp//sbin/nologin
sync//bin/sync
shutdown//sbin/shutdown
halt//sbin/halt
mail//sbin/nologin
operator//sbin/nologin
games//sbin/nologin
ftp//sbin/nologin
nobody//sbin/nologin
systemd-network//sbin/nologin
dbus//sbin/nologin
polkitd//sbin/nologin
sshd//sbin/nologin
postfix//sbin/nologin
fox/bin/fox
8.5 将passwd文件的用户id数值追加1,并以序列化形式输出
[root@rancher test]# awk -F: -v a=1 '{print "UserName:"$1",UserId:"$3+a}' /data/app/test/passwd
8.6 awk内置的一些变量
- FILENAME:文件名
- NR:Number of Records(文件总行数)
- NF:Number of fields(文件的列)
[root@rancher test]# awk -F: '{print FILENAME NR NF}' /data/app/test/passwd
/data/app/test/passwd17
/data/app/test/passwd27
/data/app/test/passwd37
/data/app/test/passwd47
/data/app/test/passwd57
/data/app/test/passwd67
/data/app/test/passwd77
/data/app/test/passwd87
/data/app/test/passwd97
/data/app/test/passwd107
/data/app/test/passwd117
/data/app/test/passwd127
/data/app/test/passwd137
/data/app/test/passwd147
/data/app/test/passwd157
/data/app/test/passwd167
/data/app/test/passwd177
/data/app/test/passwd187
8.6 查看空行的行号
[root@rancher test]# cat sed.txt
dong shen guang
guan zhen dong
wo wo
my fox so handsome
lai lai
le le
[root@rancher test]#
[root@rancher test]# awk '/^$/ {print NR}' /data/app/test/sed.txt
5
===demo
chenji.ext
张三 40
李四 50
王武 60
8.7 计算第二列的和并列加
[root@rancher test]# cat chenji.txt
张三 40
李四 50
王五 69
[root@rancher test]# cat chenji.txt | awk -F " " '{sum+=$2} END{print "Total:"sum}'
Total:159
九 sort 将文件进行排序,将排序结果标准输出
9.1 基本语法
sort (选项)(参数)
- -n 依照数值大小进行排序
- -r 以相反的顺序进行排序
- -t 设置排序时所有分割字符串
- -k 指定需要排序的列
9.2 排序例子
[root@rancher test]# cat sort.txt
aa:20:11
bb:40:5.4
cc:23:12
dd:56:78
[root@rancher test]#
[root@rancher test]# sort -t : -nrk 2 sort.txt
dd:56:78
bb:40:5.4
cc:23:12
aa:20:11
十、企业常用例子
10.1判断文件是否存在,不过不存在如何处理
[root@rancher test]# cat file.sh
#!/bin/bash
if [ -f $1 ];then
echo "文件存在"
else
echo "文件不存在"
fi
[root@rancher test]# ll
-rw-r--r-- 1 root root 31 Jul 15 21:41 hello.sh
-rw-r--r-- 1 root root 87 Jul 16 17:41 if.sh
[root@rancher test]# bash file.sh file.txt
文件不存在
[root@rancher test]# bash file.sh if.sh
文件存在
10.2对无序的一列数进行排序并累加
[root@rancher test]# cat test.txt
1
23
32
4
6
[root@rancher test]# sort -n test.txt | awk '{a+=$0;print $0} END{print "Total:"a}'
1
4
6
23
32
Total:66
10.3查看文件夹中,文本内容包含有“fox”的文件名称
[root@rancher test]# grep -r "if" /data/app/test
/data/app/test/if.sh:if [ $1 -eq 1 ];then
/data/app/test/if.sh:elif [ $1 -eq 2 ];then
/data/app/test/file.sh:if [ -f $1 ];then
[root@rancher test]# grep -r "if" /data/app/test |cut -d ":" -f 1
/data/app/test/if.sh
/data/app/test/if.sh
/data/app/test/file.sh
10.4 截取IP
[root@rancher test]# ifconfig ens33 |grep "inet" |grep "broadcast" |awk '{print $2}'
192.168.8.21