Shell脚本基础及常用的四剑客

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 本篇内容记录了一些语句的代码编写和应用。

Shell脚本基础及应用


一、shell变量


一、 定义变量时,变量名不加美元符号($,PHP语言中变量需要)


如: your_name=“runoob.com”


命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。 中间不能有空格,可以使用下划线(_)。 不能使用标点符号。


不能使用bash里的关键字(可用help命令查看保留关键字)。


二、 系统变量的意义:


$?判断上一条shell命令是否正确 $#判断参数的个数 $*打印所有脚本后的参数


[root@docker1~]# cat a.sh
#! /bin/bash


参数的意义


$0 当前脚本名字

$1 脚本后第一个参数

$2 脚本后第二个参数

$?上一条是否正确,正确为0反之为1 $# 脚本后面参数的个数

$* 脚本后面所有的参数


echo "this \$0  value is $0"
echo "this \$1  value is $1"
echo "this \$2  value is $2"
echo "this \$?  value is $?"
echo "this \$#  value is $#"
echo "this \$*  value is $*"
[root@docker1 ~]# sh a.sh 12 34 
this $0  value is a.sh
this $1  value is 12
this $2  value is 34
this $?  value is 0
this $#  value is 2
this $*  value is 12 34


小实例
菜单栏实例:
[root@docker1 ~]# cat b.sh 
#! /bin/bash
echo -e '\033[32mPlease select menu follow:
echo "1)安装Apache服务器."
echo "2)安装Mysql服务器."
echo "3)安装PHP服务器."
echo "4)配置Lamp网站架构."
---------------------------------------
\033[0m'
[root@docker1 ~]# sh b.sh
Please select menu follow:
echo "1)安装Apache服务器."
echo "2)安装Mysql服务器."
echo "3)安装PHP服务器."
echo "4)配置Lamp网站架构."
----------------------------------


二、判断语句


if语句


1、if语句实例


shell里,(())表示比较大小


if 语法格式为:


if 表达式;then
表达式
else
表达式
if


if语句判断数字大小:


[root@docker1 ~]# cat c.sh 
#! /bin/bash
NUM1=100
NUM2=200
if (($NUM1 > $NUM2));then
  echo "This $NUM1 great $NUM2"
else
  echo "This $NUM1 little $NUM2"
fi
[root@docker1 ~]# sh c.sh 
This 100 little 200


  • 逻辑运算符:

-f 判断文件是否存在

-d 判断目录是否存在

-eq 等于

-ne 不等

-lt 小于

-gt 大于

-le 小于等于

-ge 大于等于

-a 双方都成立,逻辑表达式

-o 单方成立

-z 空字符串


 实例: 1)判断一个目录是否存在 [root@docker1 ~]# cat d.sh 
   #! /bin/bash
# 判断文件是否存在
DIR=/data/20200522
if [ ! -d /data/$DIR ]; then
  mkdir -p /data/$DIR
  echo -e "\033[32mThis $DIR is create success!\033[0m"
else
  echo -e "\033[32mThis $DIR is already exist,Please exit.\033[0m"
fi
[root@docker1 ~]# sh d.sh 
This /data/20200522 is already exist,Please exit.
2)判断一个文件是否存在
[root@docker1 shell]# cat a.sh 
#! /bin/bash
FILE=/tmp/20200222.txt
if [ ! -f $FILE ];then
  echo "OK" >> $FILE
else
  cat $FILE
fi
[root@docker1 shell]# sh a.sh 
[root@docker1 shell]# sh a.sh 
OK
3)多个条件测试判断
[root@docker1 shell]# cat b.sh 
#!/bin/bash
score=$1
if [ -z $1 ];then
  echo "Please input your score{80|90|100}"
exit
fi
if [ $score -gt 85 ];then
  echo "best"
elif [ $score -gt 75 ];then
  echo "good"
elif [ $score -gt 60 ];then
  echo "pass"
else
  echo "no pass"
fi
[root@docker1 shell]# sh b.sh 
Please input your score{80|90|100}
[root@docker1 shell]# sh b.sh 60
no pass
[root@docker1 shell]# sh b.sh 100
best


if语句实战


https://blog.csdn.net/qq_45714272/article/details/106296310

https://blog.csdn.net/qq_45714272/article/details/106299071


三、循环语句


for循环


1、打印1到15的和利用for循环
[root@a ~]# cat a.sh 
#! /bin/bash
for i in `seq 15`
do
  echo "the number is $i"
done
2、查看脚本运行过程
[root@a ~]# sh -x b.sh
3、打印1到100的和
[root@a ~]# cat b.sh 
#! /bin/bash
j=0
for ((i=1;i<=100;i++))
do
  j=`expr $i + $j`
done
echo $j
For循环企业实例
1、打印当前目录所有sh结尾的文件并打包
[root@a ~]# cat c.sh
#! /bin/bash
for i in `find . -maxdepth 1  -name "*.sh"`
do 
  tar -czvf $i.tgz $i
done
[root@a ~]# ls
anaconda-ks.cfg  a.sh  a.sh.tgz  b.sh  b.sh.tgz  c.sh  c.sh.tgz
解压:
[root@a ~]# cat c.sh 
#! /bin/bash
for i in `find . -maxdepth 1  -name "*.sh"`
do 
  tar -czvf $i.tgz $i
done
[root@a ~]# sh c.sh
./a.sh
./b.sh
./c.sh
[root@a ~]# cd /tmp/test/
[root@a test]# ls
a.sh  b.sh  c.sh
5、远程主机批量传输文件
传输单个文件
[root@a test]# cat auto_scp 
#! /bin/bash
# auto scp files for client
# by 20200524 caq
for i in `echo 175.24.20.189`
do 
  scp -r /tmp/test root@$i:/root
done
[root@a test]# sh auto_scp 
root@175.24.20.189's password: 
a.sh                                                    100%   64     1.2KB/s   00:00    
b.sh                                                    100%   76     1.4KB/s   00:00    
c.sh                                                    100%   89     1.6KB/s   00:00    
auto_scp                                                100%  131     2.4KB/s   00:00 
传输多个文件
[root@a test]# cat auto_scp 
#! /bin/bash
# auto scp files for client
# by 20200524 caq
FILES=$*
if [ -z $* ];then
  echo "input your patameter!{files|dir|...}"
  exit
fi
for i in `echo 175.24.20.189`
do 
  scp -r $FILES root@$i:/root/
done
  [root@a test]# sh auto_scp /a1 /a2
root@175.24.20.189's password:  
[root@VM_0_12_centos ~]# ls
a1  a2  test
免密登录
[root@a test]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:l+BheWrW/7HYGue2TlkGWTPW+bstC19H1SIOAgAmJEM root@a
The key's randomart image is:
+---[RSA 2048]----+
|*Eo....        ++|
|.+     . .    .+=|
|        * o . + +|
|       o B + . oo|
|        S + .   =|
|       o . .   * |
|            + = =|
|             @o=o|
|            o+X+ |
+----[SHA256]-----+
[root@a .ssh]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@175.24.20.189
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@175.24.20.189's password: 
Number of key(s) added: 1
Now try logging into the machine, with:   "ssh 'root@175.24.20.189'"
and check to make sure that only the key(s) you wanted were added.
[root@a .ssh]# ssh 175.24.20.189
Last login: Sun May 24 21:43:32 2020 from 123.162.210.87


while循环


While循环企业实例:
IP等信息在一个文件中进行批量传输:
[root@a shell]# cat c.sh 
#! /bin/bash
#by 20200524
while read line
do
  ip=`echo $line |awk '{print $2}'`
  echo "scp -r /tmp/text.txt root@$ip:/tmp"
done < list.txt
列表信息为:
[root@a shell]# cat list.txt 
1 192.168.1.1
2 192.168.1.2
3 192.168.1.3
4 192.168.1.4
实现打印文件内容中的部分内容,并进行操作
[root@a shell]# sh c.sh 
scp -r /tmp/text.txt root@192.168.1.1:/tmp
scp -r /tmp/text.txt root@192.168.1.2:/tmp
scp -r /tmp/text.txt root@192.168.1.3:/tmp
scp -r /tmp/text.txt root@192.168.1.4:/tmp


until循环


Until循环
这个循环语句用的较少
还是通过一个实例来理解它吧!
[root@a shell]# cat f.sh 
#! /bin/bash
a=10
until [[ a -lt 0 ]]
do
  echo "$a"
  ((a--))
done
[root@a shell]# sh f.sh 
10
9
8
7
6
5
4
3
2
1
0


四、选择语句


case语句


1、case语句简单实例
# case语句用来判断,下面这个实例打印了一个菜单列表
语法格式为:
    case variable in
        option )
        cmd
        ;;
        option )
        cmd
        ;;
        ... )
        cmd
        ;;
        * )
        cmd
        ;;
  esac      
[root@a shell]# cat e.sh 
#/bin/bash
case $1 in
  apache )
  echo "wait install apache server!"
  ;;
  mysql )
  echo "wait install mysql server!"
  ;;
  php )
  echo "wait install php server!"
  ;;
  * )
  echo "input your install server name please!"
  ;;
esac
[root@a shell]# sh e.sh 
input your install server name please!
[root@a shell]# sh e.sh mysql
wait install mysql server!
2、select选择语句和case语句结合使用
select一般用于选择菜单的创建,可以配合ps3来做菜单的打印输出信息。
[root@a shell]# cat e.sh 
#/bin/bash
ps3="select your menu:"
select i in "apache" "mysql" "php"
do
case $i in
  apache )
  echo "wait install apache server!"
  ;;
  mysql )
  echo "wait install mysql server!"
  ;;
  php )
  echo "wait install php server!"
  ;;
   * )
        echo "input your install server name please!"
        ;;
esac
done
[root@a shell]# sh e.sh 
1) apache
2) mysql
3) php
#? 1
wait install apache server!
#? 2
wait install mysql server!
#? 3
wait install php server!


五、四剑客


grep


grep 多用作匹配
sed多用于修改
awk多用于打印特定位置字符
sed命令可以实现不打开文件的情况下对文件内容进行修改
sed的替换命令格式:s/A/B/g 或者知 s#A#B#g 或者 s_A_B_g#。
s 是替代命令. s/表达式/replacement/
空白用t替代。
g(GLOBAL)
g -- 全部替代
无g -- 只替代每行第一个。
修改文件内容
[root@a shell]# cat a.txt 
my name is caq
abc
def
预修改
[root@a shell]# sed 's/caq/kebi/g' a.txt
my name is kebi
abc
def
真实修改(-i,insert)
[root@a shell]# sed -i 's/caq/kebi/g' a.txt
3
对文件内容加上空格
^表示文档开头
$表示行尾
a表示下一行
i表示上一行
p代表打印
&表示添加内容,我后面有个空格就代表在文档开头加上空格,加数字,加符号都是可以的


sed


一般特殊符号要出现必须用转义字符


\' \" \* \? \\ \~ \` \! \# \$ \&  \|


如下,我想替换\t为空格


我们就可以用转义字符加在\t的前面


caq@C:~/C/code/point$ cat  malloc.c 
#include <stdio.h>
#include <stdlib.h>
int main()
{
  int *x;
  printf("x value: %p\t,x address: %p\t,*x value:%d\t",x,&x,*x);
  x = (int *)malloc(sizeof(x));
        printf("x value: %p\t,x address: %p\t,*x value:%d\t",x,&x,*x);
  *x = 10;
  printf("x value: %p\t,x address: %p\t,*x value:%d\t",x,&x,*x);
  free(x);
  return 0;
}
预替换
caq@C:~/C/code/point$ sed "s:\\\t: :g" malloc.c 
#include <stdio.h>
#include <stdlib.h>
int main()
{
  int *x;
  printf("x value: %p ,x address: %p ,*x value:%d ",x,&x,*x);
  x = (int *)malloc(sizeof(x));
        printf("x value: %p ,x address: %p ,*x value:%d ",x,&x,*x);
  *x = 10;
  printf("x value: %p ,x address: %p ,*x value:%d ",x,&x,*x);
  free(x);
  return 0;
}
加上-i参数真实替换
caq@C:~/C/code/point$ sed -i "s:\\\t: :g" malloc.c 
再次查看是否替换成功
caq@C:~/C/code/point$ cat malloc.c 
#include <stdio.h>
#include <stdlib.h>
int main()
{
  int *x;
  printf("x value: %p ,x address: %p ,*x value:%d ",x,&x,*x);
  x = (int *)malloc(sizeof(x));
        printf("x value: %p ,x address: %p ,*x value:%d ",x,&x,*x);
  *x = 10;
  printf("x value: %p ,x address: %p ,*x value:%d ",x,&x,*x);
  free(x);
  return 0;
}


sed实例:
行首添加
[root@a shell]# sed 's/^/& /g' a.txt
 my name is kebi
 abc
 def
[root@a shell]# sed  -i 's/^/& /g' a.txt
[root@a shell]# cat a.txt 
 my name is kebi
 abc
 def
 行尾添加
 [root@a shell]# sed 's/$/& aaa/g' a.txt
 my name is kebi aaa
 abc aaa
 def aaa
 [root@a shell]# sed -i  's/$/& aaa/g' a.txt
[root@a shell]# cat a.txt 
 my name is kebi aaa
 abc aaa
 def aaa
 下一行添加内容
 先进行匹配,找到my所在行,之后在起一行
 [root@a shell]# sed '/my/a new line' a.txt 
 my name is kebi aaa
new line
 abc aaa
 def aaa
上一行
[root@a shell]# sed '/my/i new line' a.txt 
new line
 my name is kebi aaa
 abc aaa
 def aaa
打印特定一行
[root@a shell]# sed -n '/kebi/p' a.txt 
 my name is kebi aaa
打印多行
[root@a shell]# sed -n '1,3p' a.txt 
 my name is kebi aaa
 abc aaa
 def aaa
对文档进行排序和取最值
[root@a shell]# cat b.txt 
#! /bin/bash
2321234123
43214214 34231
524524 4254 2425
4254543 245245
54325
[root@a shell]# cat b.txt |sed 's/ /\n/g'|sort -nr|sed -n '1p;$p'
2321234123
2425


awk


awk实例:
语法格式:
awk -option '{print $n}'
F表示分隔符
打印某一列元素
[root@a shell]# cat a.txt 
my name is kebi aaa
[root@a shell]# cat a.txt |awk '{print $1}'
my
以:为分隔符打印第一列
[root@a shell]# cat /etc/passwd |awk -F : '{print $1}'
root
bin
daemon
...
...
打印网卡IP地址
[root@a shell]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:24:e5:c3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.10/24 brd 192.168.1.255 scope global noprefixroute ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::a0b8:9a41:6d1b:7285/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
[root@a shell]# ip a | egrep "inet"|awk '{print $2}'|sed -n '3p'
192.168.1.10/24
查看根目录使用率
[root@a shell]# df -h
Filesystem               Size  Used Avail Use% Mounted on
devtmpfs                 475M     0  475M   0% /dev
tmpfs                    487M     0  487M   0% /dev/shm
tmpfs                    487M  7.5M  479M   2% /run
tmpfs                    487M     0  487M   0% /sys/fs/cgroup
/dev/mapper/centos-root   17G  2.2G   15G  13% /
/dev/sr0                 4.4G  4.4G     0 100% /mnt/centos
/dev/sda1               1014M  136M  878M  14% /boot
tmpfs                     98M     0   98M   0% /run/user/0
[root@a shell]# df -h|grep "/$" |awk '{print $5}'|sed s/%//g
13
利用awk增加注解:
[root@a shell]# cat a.txt |awk '{print "1:" $NF}'
1:aaa


find


find案例
mtime为查找时间,-1为今天创建的文件
exec这个参数用于把find命令搜索到的结果交给紧随其后的命令做进一步处理
{}表示前面得到的结果
cmd -exec rm -rf {} \
表示把前面得到的结果删除固定格式
找到某文件,并删除
[root@a shell]# find . -maxdepth 1 -type f -name "*.sh" -mtime -1
./a.sh
[root@a shell]# find . -maxdepth 1 -type f -name "*.sh" -mtime -1 -exec rm -rf {} \;
[root@a shell]# find . -maxdepth 1 -type f -name "*.sh" -mtime -1
xargs同-exec都有这个功能
[root@a tmp]# find . -maxdepth 1 -type f -name "*.txt" -mtime -1 |xargs rm -rf {}  \;
[root@a tmp]# ls
找到某文件并复制到指定位置
[root@a shell]# find . -maxdepth 1 -type f -name "*.txt" -mtime -1 -exec cp {} /tmp \;
[root@a shell]# cd /tmp
[root@a tmp]# ls
a.txt
b.txt
systemd-private-32cf4ca75eb6423d957b2b2a4be4d975-chronyd.service-HpBhoN
test
vmware-root_685-4013788754
vmware-root_687-4022112208
vmware-root_689-4021587913
找到内存大于多少的文件并移动到指定目录
[root@a ~]# find . -maxdepth 1 -size +100M -type f
./RHEL-server-7.0-x86_64-
[root@a ~]# find . -maxdepth 1 -size +100M -type f -exec mv {} /tmp \;
[root@a ~]# cd /tmp
[root@a tmp]# ls
RHEL-server-7.0-x86_64-
systemd-private-32cf4ca75eb6423d957b2b2a4be4d975-chronyd.service-HpBhoN
test
vmware-root_685-4013788754
vmware-root_687-4022112208
vmware-root_689-4021587913


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
Shell
蓝易云 - 简单shell脚本的编写教程
以上就是编写一个基本Shell脚本的步骤。当然,Shell脚本可以做的远不止这些,你可以使用变量,控制结构(如if语句和循环),以及各种Shell命令和功能来编写更复杂的脚本。
11 1
|
14天前
|
监控 Shell Linux
Linux的Shell脚本详解
Linux的Shell脚本详解
|
19天前
|
Shell
shell脚本
shell脚本
18 2
|
4天前
|
Shell 调度
Shell脚本中的if条件判断语句
Shell脚本中的if条件判断语句
|
4天前
|
Shell
蓝易云 - 简单shell脚本的编写教程
以上就是编写一个基本Shell脚本的步骤。当然,Shell脚本可以做的远不止这些,你可以使用变量,控制结构(如if语句和循环),以及各种Shell命令和功能来编写更复杂的脚本。
5 0
|
27天前
|
Ubuntu Java Linux
Linux centos7 ubuntu 一键安装Java JDK 脚本 shell 脚本
Linux centos7 ubuntu 一键安装Java JDK 脚本 shell 脚本
38 2
|
28天前
|
Shell Linux
shell循环读文件 Linux脚本读文件
shell循环读文件 Linux脚本读文件
18 3
|
4天前
|
机器学习/深度学习 Unix Java
技术笔记:Linux之Shell脚本编程(一)
技术笔记:Linux之Shell脚本编程(一)
|
27天前
|
Shell Linux
shell linux中shell脚本编写俄罗斯方块
shell linux中shell脚本编写俄罗斯方块
22 1
|
27天前
|
Shell Linux Perl
Linux shell脚本sed使用
Linux shell脚本sed使用
16 1