Shell脚本入门与简单实战

一.基本概念

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 [ $a -ne 1 -a $a != 2 ]。
  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
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Linux Shell高级技巧实战总结 一、将输入信息转换为大写字符后再进行条件判断 二、为调试信息设置输出级别 三、判断参数是否为数字 四、判断整数变量的奇偶性 五、将Shell命令赋值给指定变量,以保证脚本的移植性 六、获取当前时间距纪元时间(1970年1月1日)所经过的天数 七、非直接引用变量 八、在循环中使用管道的技巧 九、自链接脚本 十、Here文档的使用技巧 十一、获取进程的运行时长(单位: 分钟) 十二、模拟简单的top命令 十三、格式化输出指定用户的当前运行进程 十四、用脚本完成which命令的基本功能 十五、验证输入信息是否合法 十六、整数验证 十七、判断指定的年份是否为闰年 十八、将单列显示转换为多列显示 十九、将文件的输出格式化为指定的宽度 二十、监控指定目录下磁盘使用空间过大的用户 二十一、编写一个更具可读性的df命令输出脚本 二十二、编写一个用于添加新用户的脚本 二十三、kill指定用户或指定终端的用户进程 二十四、判断用户输入(是/否)的便捷方法 二十五、通过FTP下载指定的文件 二十六、文件锁定 二十七、用小文件覆盖整个磁盘 二十八、统计当前系统中不同运行状态的进程数量 二十九、浮点数验证 三十、统计英文文章中每个单词出现的频率 Linux Shell经典实例解析--Oracle启动脚本(上) Linux Shell经典实例解析--Oracle启动脚本(下)
Shell脚本高级编程教程,希望对你有所帮助。 Example 10-23. Using continue N in an actual task: 1 # Albert Reiner gives an example of how to use "continue N": 2 # --------------------------------------------------------- 3 4 # Suppose I have a large number of jobs that need to be run, with 5 #+ any data that is to be treated in files of a given name pattern in a 6 #+ directory. There are several machines that access this directory, and 7 #+ I want to distribute the work over these different boxen. Then I 8 #+ usually nohup something like the following on every box: 9 10 while true 11 do 12 for n in .iso.* 13 do 14 [ "$n" = ".iso.opts" ] && continue 15 beta=${n#.iso.} 16 [ -r .Iso.$beta ] && continue 17 [ -r .lock.$beta ] && sleep 10 && continue 18 lockfile -r0 .lock.$beta || continue 19 echo -n "$beta: " `date` 20 run-isotherm $beta 21 date 22 ls -alF .Iso.$beta 23 [ -r .Iso.$beta ] && rm -f .lock.$beta 24 continue 2 25 done 26 break 27 done 28 29 # The details, in particular the sleep N, are particular to my 30 #+ application, but the general pattern is: 31 32 while true 33 do 34 for job in {pattern} 35 do 36 {job already done or running} && continue 37 {mark job as running, do job, mark job as done} 38 continue 2 39 done 40 break # Or something like `sleep 600' to avoid termination. 41 done 42 43 # This way the script will stop only when there are no more jobs to do 44 #+ (including jobs that were added during runtime). Through the use 45 #+ of appropriate lockfiles it can be run on several machines 46 #+ concurrently without duplication of calculations [which run a couple 47 #+ of hours in my case, so I really want to avoid this]. Also, as search 48 #+ always starts again from the beginning, one can encode priorities in 49 #+ the file names. Of course, one could also do this without `continue 2', 50 #+ but then one would have to actually check whether or not some job 51 #+ was done (so that we should immediately look for the next job) or not 52 #+ (in which case we terminate or sleep for a long time before checking 53 #+ for a new job).

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值