Linux的Shell介绍

菜单

一、常用的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