Shell脚本入门与简单实战一.基本概念二.基础入门三

一.基本概念

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
在计算机科学中,Shell俗称壳(用来区别于核),是指“为使用者提供操作界面”的软件(command interpreter,命令解析器)。
Linux shell属于一种图形化shell界面,并且shell脚本指的是运行在shell上的脚本。

二.基础入门

1.基础语法格式与标准

自定义shell脚本通常被放于/usr/local/sbin目录下,这样方便标准统一,shell脚本通常以sh结尾,比如test.sh

#! /bin/bash

## 这是第一个shell
date
echo 'Hello world!'
ls
复制代码

其中,第一行#! /bin/bash必须要有,#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell(这里用的是bash)。
echo用于向窗口输出文本,文本用单引号括起来,执行结果如下:

[root@VM-12-14-centos sbin]# sh test.sh 
Wed Aug  4 11:00:46 CST 2021
Hello,word!
test.sh
复制代码
  • #!/bin/bash 指定脚本要使用的 Shell 类型为 Bash 。
  • #! 被称为 Sha-bang ,或者 Shebang , Linux 会分析它之后的指令,并载入该指令作为解析器。
  • ls 就是脚本文件的内容了,表明我们执行 hello.sh 脚本时会列举出当前目录的文件列表并且会向控制台打印 hello world

shell脚本的执行方式常用的有两种:

  1. 如果为非Root用户,可以给脚本添加执行权限(因为vim编辑默认不带执行权限)
  • chmod +x test.sh #给此脚本test.sh添加执行权限
  • ./test.sh #执行当前目录下的脚本
  1. sh test.sh 直接执行

也可以使用sh -x test.sh 显示执行过程,方便排查脚本错误

shell中常用的date命令
date "+%Y-%m-%d %H:%M:%S" 2021-08-01 12:25:10
date -d "+1 day" "%Y-%m-%d" 加一天
date -d "-1 year" "%Y-%m-%d" 减一年

(1)基本运算符与参数赋值

  1. $[ ] : 加减乘除,不必添加空格
  2. $(( )) :加减乘除等,不必添加空格
#! /bin/bash
a=1
b=2
sum=$[$a+$b]
echo "12345+$sum"
echo "------------"
echo "第一个数:"
read  x
echo ”第二个数:
read y
sum=$[$x+$y]
echo "这是两个数的和:$sum"
复制代码

执行结果如下:

[root@VM-12-14-centos sbin]# sh test.sh 
2021-08-04 11:44:42
Hello,word!
test.sh
12345+3
------------
第一个数:
999
”第二个数:
999
这是两个数的和:1998
复制代码

read x/a/b/c/d 还可以替换为read -p “字符串” x/a/b/c/d

read -p "当前结果满意吗:y/N" x
复制代码

read -p相当于echo的效果上进行输入

(2)条件判断语句

基本条件判定符号如下:

  1. 条件在(( ))双括号中使用,可用 参数名 + >= ,<=,>,<,=
  2. 条件在[ ]方括号中使用,使用 -lt (小于),-gt (大于),-le (小于等于),-ge (大于等于),-eq (等于),-ne (不等于)。
  3. [] : 中括号旁边和运算符两边必须添加空格 (可以使用,不推荐)
  4. [[ ]]:中括号旁边和运算符两边必须添加空格 (字符串验证时,推荐使用)
  5. (()) : 中括号旁边和运算符两边必须添加空格 (数字验证时,推荐使用)
  6. [[]] 和 (()) 分别是[ ]的针对数学比较表达式和字符串表达式的加强版。
  7. 使用[[ … ]]条件判断结构,而不是[ … ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ a != 1 && a != 2 ]], 如果不适用双括号, 则为if [ a -ne 1] && [ a != 2 ]或者if [
    ane1aa -ne 1 -a

  8. [[ ]]中增加模式匹配特效;
  9. (( ))不需要再将表达式里面的大小于符号转义,除了可以使用标准的数学运算符外,还增加了以下符号

【1】if

#! /bin/bash
read -p "请输入你的成绩:" a
if ((a>=60));then
	echo "你的成绩及格了,恭喜你!"
fi
复制代码

【2】if else

#! /bin/bash
read -p "请输入你的成绩:" a
if ((a>=60));then
	echo "你的成绩及格了,恭喜你!"
else
   echo "你的成绩没及格,下次加油!"
fi
复制代码

【3】if elif else

#!/bin/bash
read -p "请输入你的成绩:" a
if ((a>=60)) && ((a<=90));then
   echo "你的成绩及格了,恭喜你!"
elif ((a>90));then
   echo "你的成绩非常优秀!"
else
   echo "你的成绩没及格,下次加油!"
fi
复制代码

image.png
或者
image.png
运行结果图如下
image.png

【4】case语句

#!/bin/bash
read -p "请输入你想判断的整数:" x
a=$[$x%2]
case $a in
1)
        echo "这是一个奇数!"
        ;;
0)
        echo "这是一个偶数!"
        ;;
esac
复制代码

Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
case需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break,其中“;;”不是跳出循环,是不在去匹配下面的模式

  1. break :跳出总循环
  2. continue:跳出当前循环,继续下一次循环

case脚本常用于编写系统服务的启动脚本。
image.png
image.png

【5】while

#条件循环
while condition
do
    command
done

#无限循环
while :
do
    command
done
复制代码

【6】until循环

until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。

until condition
do
    command
done
复制代码

【7】for循环

for 变量名 in 循环的条件; do
command
done

#!/bin/bash
for i in `seq 1 5`;do
        echo $i
done
复制代码

seq 1 5 代表1到5的一个序列

(3)输出语句

【1】echo

仅建议用于字符串的输出
echo " " 或者echo ' '

【2】printf

printf 不会像 echo 自动添加换行符,我们可以手动添加 \n
无大括号,直接以空格分隔

  • 格式:printf format-string [arguments...] 其中(format-string: 格式控制字符串、arguments: 参数列表)
  • 案例:printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234

%s %c %d %f 都是格式替代符:

  1. d:Decimal 十进制整数 对应位置参数必须是十进制整数,否则报错!
  2. s:String 字符串 对应位置参数必须是字符串或者字符型 否则报错
  3. c:Char 字符 对应位置参数必须是字符串或者字符型 否则报错
  4. f:Float 浮点 对应位置参数必须是数字型 否则报错
  5. %-10s : 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
  6. %-4.2f :指格式化为小数,宽度为4个字符,其中.2指保留2位小数。

转义符:

  1. \a :警告字符,通常为ASCII的BEL字符
  2. \b :后退
  3. \c :抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
  4. \f :换页(formfeed)
  5. \n :换行
  6. \r :回车(Carriage return)
  7. \t :水平制表符
  8. \v :垂直制表符
  9. \ :一个字面上的反斜杠字符
  10. \ddd :表示1到3位数八进制值的字符。仅在格式字符串中有效
  11. \0ddd :表示1到3位的八进制值字符

(4)shell脚本中的函数

函数建议写在开头,函数永远要在调用之前,
使用$1来代表第一个参数,便于按顺序传参
可以在脚本内调用方法,也可以在脚本外调用方法

#!/bin/bash
function add(){
        sum=$[$1 + $2]
        return $sum
}

add 1 2
echo "当前和为:$? !"
复制代码

和为3


#!/bin/bash
function add(){
        sum=$[$1 + $2]
        return $sum
}

add $1 $2
echo "当前和为:$? !"
复制代码
sh hanshu.sh 3 6
复制代码

当前和为:9 !

(5)常用文件操作

shell 脚本中if还经常判断关于档案属性,比如判断是普通文件还是目录,判断文件是否有读写执行权限等。常用的也就几个选项:

  • -e :判断文件或目录是否存在
  • -d :判断是不是目录,并是否存在
  • -f :判断是否是普通文件,并存在
  • -r :判断文档是否有读权限
  • -w :判断是否有写权限
  • -x :判断是否可执行

使用if判断时,具体格式为: if [ -e filename ] ; then

三.实战入门

1.入门练手

(1)1-100的和

#!/bin/bash
a=1
sum=0
b=1
while (($a<=100))
do
        sum=$[$a+$sum]
        a=$[$b+$a]
done

echo $sum 
复制代码

(2)输入一个数,求从1-n的和

#bin/bash
sum=0
read -p "请输入一个数字:" a
while ((a<1))
do
        read -p "输入的数字格式不正确,请重新输入一个数字:" a
done

for i in `seq 1 $a`;do
        sum=$[$i+$sum]
done
echo $sum
复制代码

(3)拷贝一个目录到另一个目录下

shell脚本对文件目录的判定

shell 脚本中if还经常判断关于档案属性,比如判断是普通文件还是目录,判断文件是否有读写执行权限等。常用的也就几个选项:

-e :判断文件或目录是否存在

-d :判断是不是目录,并是否存在

-f :判断是否是普通文件,并存在

-r :判断文档是否有读权限

-w :判断是否有写权限

-x :判断是否可执行

使用if判断时,具体格式为: if [ -e filename ] ; then
复制代码

#!/bin/bash
cd /home/xt
list=`ls`
for i in ${list[0]}
do
        echo "$i"
        if [ -d $i ];then
           echo "123456"
           cp -r $i /home/test1/
        fi
done
或者********************************
#! /bin/bash
for f in `ls /root/`; do
	if [ -d $f ] ; then
		cp -r $f /tmp/
	fi
done
复制代码

2.文件信息处理

awk处理文件

#!/bin/bash
awk -F "," '{print NF,$1,$2,$3,$4,$5,$6,$7}' a.txt

awk -F "," '{print NF,$0}' a.txt
复制代码

image.png
直接读取文件,输出第123457列的数据
$0直接输出所有的数据,

3.实用脚本

(1)开启/关闭Tomcat

sh tomcat.sh start/stop
开启tomcat,并进入tomcat的日志
关闭tomcat,并判断是否要杀死僵尸进程,删除webapps下的war包

#!/bin/bash
tomcat_home=/home/xt/test-tomcat
STARTTOMCAT=$tomcat_home/bin/startup.sh
SHUTDOWN=$tomcat_home/bin/shutdown.sh
WEB=$tomcat_home/webapps
MYLOG=/applog/ossDown-downBatch
TOMCATLOG=$tomcat_home/logs
case $1 in
start)
        echo "启动Tomcat!"
        $STARTTOMCAT
        cd $TOMCATLOG
        tail -f catalina.out -n 500
        ;;
stop)
        echo "关闭Tomcat!"
        $SHUTDOWN
        pid=`ps -ef |grep test-tomcat |grep -v "grep"|awk '{print $2}'`
        if [ "$pid" = "" ];then
                echo "当前tomcat线程已停止"
        else
                echo "关闭的进程号为: $pid"
                kill -9 $pid
        fi
        cd $WEB
        rm -rf *
        ;;

esac
复制代码