【运维知识高级篇】超详细的Shell编程讲解1(Shell作用+脚本书写方式+脚本执行方式+变量分类+变量配置文件+变量定义+Shell重要的位置变量+三种传参方式)

简介: 【运维知识高级篇】超详细的Shell编程讲解1(Shell作用+脚本书写方式+脚本执行方式+变量分类+变量配置文件+变量定义+Shell重要的位置变量+三种传参方式)

学习Shell编程对于一个运维来说至关重要,现在岗位上基本都要求运维,懂1门脚本语言,或是Shell或是python,今天我们就展开Shell编程的讲解,这也是运维知识高级篇的第一篇,带大家从基础运维向中级运维转变。

Shell的作用

1. 1、安装操作系统可以选择自动安装(无人值守安装软件cobbler、kickstart) 底层调用shell脚本
2. 2、优化操作系统(防火墙优化 selinux关闭 SSH优化 加大文件描述符 修改默认YUM仓库 EPEL仓库 时间同步 关闭NetworkManager 安装常用软件 内核参数优化... ) 写入到脚本文件中
3. 3、安装部署服务(Nginx Apache PHP MySQL Redis Tomcat....)写入脚本
4. 4、业务数据统计(Linux命令) 统计好后可以定时发到领导邮箱,写入脚本+定时任务
5. 5、大文件切割(防止日志文件过大) 写成shell脚本
6. 6、辅助公司自研的(不成熟的)程序正常运行
7. 7、监控 脚本取值+定时任务-->发送到邮箱
8. 8、系统底层服务都是使用shell脚本,自研发程序或py程序
9. 9、简化操作步骤
10. 
11. vim start_py.sh
12. nohup python3.5 test.py -redis-ip=172.16.1.51 -redis-port=6379 xxx &
13. vim stop_py.sh   
14. ps axu|grep test.py|grep -v grep|awk '{print $2}'|xargs kill -9

学习Shell编程必备知识

1. 1、Linux基础命令,重点关注awk sed grep
2. 2、正则表达式
3. 3、熟练使用vim(各种快捷键)
4. 4、Xshell远程连接工具

如何学好Shell编程

1. 1、内容不多,主要是变量 比较表达式 if判断 for循环 while循环 流程控制语句 case语句 函数function 数组等等
2. 2、先可以读懂别人的代码,进行简单的修改代码,能够独立编写简单的脚本,一开始可以先用命令堆积(熟练后使用语句)
3. 3、多看案例,多看其他人编写的脚本,学习他人思路,变成自己思路
4. 4、切忌拿来既用
5. 5、代码的每行不是特别的理解的、使用中文注释
6. 6、有一本适合自己的教材或者是详细的笔记
7. 7、要有编程思维(来源于生活)

Shell入门

一、什么是Shell

Shell是命令解释器,Linux默认的Shell是: bash

Shell分交互式与非交互式

交互式:输入命令可以得到响应

非交互式:通过脚本运行Shell命令,无需等待用户输入命令

二、什么是Shell脚本

将基础命令写入到文件中称为shell脚本吗,文本中包含变量,判断语句,循环,数组等内容

Shell脚本书写方式

1. 1、Shell脚本存放在固定目录
2. 2、Shell脚本开头需要写解释器,默认使用的是bash
3. 3、Shell脚本必须以.sh结尾
4. 4、Shell脚本中最好不用中文做注释
5. 5、Shell中成对的符号一次性书写完毕
6. 6、Shell中语法一次书写完毕
7. 7、切记不使用中文符号

第一个Shell脚本

一、创建一个shell脚本

1. [root@LB00 ~]# mkdir -p /server/scripts/Day01
2. [root@LB00 ~]# cd /server/scripts/Day01
3. [root@LB00 Day01]# cat test.sh 
4. #!/bin/bash
5. echo "Hello World"

二、执行shell脚本的三种方式

1. 第一种方式: 使用解释器执行脚本中的命令  在子shell中执行
2. [root@LB00 Day01]# sh test.sh 
3. Hello World
4. [root@LB00 Day01]# bash test.sh
5. Hello World
6. 
7. 第二种方式: 使用路径的方式执行脚本 必须加x执行权限 在子shell中执行,分相对路径,绝对路径
8. [root@LB00 Day01]# chmod +x test.sh #增加了x权限,下面在敲路径时候才能用tab补齐
9. [root@LB00 Day01]# ./test.sh 
10. Hello World
11. [root@LB00 Day01]# /server/scripts/Day01/test.sh 
12. Hello World
13. 
14. 第三种执行方式: 使用source或者.执行  在父shell中执行
15. [root@LB00 Day01]# source test.sh 
16. Hello World
17. [root@LB00 Day01]# . test.sh 
18. Hello World
19. 
20. 其他shell执行方式:
21. [root@LB00 Day01]# cat test.sh |bash
22. Hello World
23. [root@LB00 Day01]# bash < test.sh 
24. Hello World

变量

一、变量的含义

1. 用一个固定不变的值来代替经常变化的值称为变量!
2. x=1 y=x+1 y=2
3. 类似书本的目录: 目录存放着具体内容

二、变量的分类

1. 环境变量(全局变量) 对于系统所有的bash生效 默认系统定义好的 都是大写
2. 普通变量(局部变量) 自己来定义的变量 一般都在脚本文件中定义
3. 全局变量先生效,局部变量后生效,所以全局变量与局部变量重复时候,最终局部变量生效
4. 
5. 按照生成周期分类:
6. 临时变量: 直接在当前shell中定义的变量 重启或者重新连接失效 name=oldboy
7. 永久变量: 写入到/etc/profile(每次xshell连接都会执行里面的变量)
8. 
9. 定义变量的两种书写方式:
10. 变量名称=变量的值         只在当前的shell中生效
11. export 变量名称=变量的值  在所有的shell中生效,但是其他连接的会话不会生效

三、变量相关的配置文件

1. 全局生效 
2. [root@lb day01]# ll /etc/profile
3. -rw-r--r-- 1 root root 1819 May 12 12:10 /etc/profile
4. 用户变量文件:
5. ~/.bashrc
6. ~/.bash_profile
7. /etc/bashrc
8. 
9. shell环境变量相关配置文件的优先级是(执行顺序同)
10. /etc/profile、~/.bash_profile、~/.bashrc、/etc/bashrc

四、变量定义方式

1. 语法:
2.     变量名称=变量的值
3. 变量名称的定义方式: 字母 数字 下划线组合,以字母或者下划线开头,不能以数字开头,等号两端不允许有空格
4. 
5. 变量名称的书写方式: 见名知其意
6. 第一种: 全大写 NAME_AGE 系统默认都是大写的
7. 第二种: 全小写 name_age
8. 第三种: 首字母大写 大驼峰语法  Name_Age
9. 第四种:首字母大写,但是首单词不大写 小驼峰语法 name_Age
10. 
11. 变量值的定义:
12. 
13. 第一种: 数字的定义,连续的数字,不连续的使用引号引起来
14. [root@LB00 ~]# age=123
15. [root@LB00 ~]# age=12 3
16. -bash: 3: command not found
17. [root@LB00 ~]# age='12 3'
18. [root@LB00 ~]# echo $age
19. 12 3
20. 
21. 第二种: 字符串定义,连续的字符串
22. [root@LB00 ~]# name=ko ten    #字符串
23. -bash: ten: command not found
24. [root@LB00 ~]# name='ko ten'
25. [root@LB00 ~]# echo $name
26. ko ten
27. [root@LB00 ~]# dir=/etc/sysconfig/network-scripts/ifcfg-eth0    #文件路径
28. [root@LB00 ~]# echo $dir
29. /etc/sysconfig/network-scripts/ifcfg-eth0
30. [root@LB00 ~]# cat $dir
31. TYPE=Ethernet
32. BOOTPROTO=none
33. NAME=eth0
34. DEVICE=eth0
35. ONBOOT=yes
36. IPADDR=10.0.0.4
37. PREFIX=24
38. GATEWAY=10.0.0.2
39. DNS1=223.5.5.5
40. [root@LB00 ~]# dir=/server/scripts/    #目录路径
41. [root@LB00 ~]# cd $dir
42. [root@LB00 scripts]# cd
43. [root@LB00 ~]# tar zcvf all.tar.gz $dir
44. tar: Removing leading `/' from member names
45. /server/scripts/
46. /server/scripts/Day01/
47. /server/scripts/Day01/test.sh
48. 
49. 第三种定义方式: 命令的定义
50. [root@LB00 ~]# test=`pwd`    #命令执行后将执行结果发送给变量,而不是每调用一次就执行一次
51. [root@LB00 ~]# echo $test
52. /root
53. [root@LB00 ~]# cd /
54. [root@LB00 /]# echo $test
55. /root
56. [root@LB00 ~]# test='pwd'    #将命令赋值给变量
57. [root@LB00 ~]# echo $test
58. pwd
59. [root@LB00 ~]# $test         #这个才是执行变量
60. /root
61. [root@LB00 ~]# cd /
62. [root@LB00 /]# $test
63. /
64. 下面同理,注意是想命令执行后给变量还是把命令给变量
65. [root@LB00 /]# test=`date +%F-%H-%M-%S`
66. [root@LB00 /]# echo $test
67. 2023-05-12-18-22-11
68. [root@LB00 /]# echo $test
69. 2023-05-12-18-22-11
70. [root@LB00 /]# test='date +%F-%H-%M-%S'
71. [root@LB00 /]# echo $test
72. date +%F-%H-%M-%S
73. [root@LB00 /]# $test
74. 2023-05-12-18-22-57
75. [root@LB00 /]# $test
76. 2023-05-12-18-22-58

还有一个进阶用法,一般在脚本内部使用,命令行不使用这个,就是变量如果没有被定义,会有默认值

1. [root@Master231 ~]# cat name.sh
2. NAME=${1:-koten}
3. echo $NAME
4. [root@Master231 ~]# sh name.sh 
5. koten
6. [root@Master231 ~]# sh name.sh boss
7. boss

五、Shell重要的位置变量

1. 5.Shell重要的位置变量
2. 
3. $0 表示脚本的名称
4. [root@LB00 Day01]# cat test.sh
5. #!/bin/bash
6. echo $0
7. [root@LB00 Day01]# sh test.sh
8. test.sh
9. 
10. 使用场景:
11. [root@LB00 Day01]# cat test.sh
12. #!/bin/bash
13. echo "Usage: $0 {start|stop|status|restart|force-reload}"
14. [root@LB00 Day01]# sh test.sh 
15. Usage: test.sh {start|stop|status|restart|force-reload}
16. [root@LB00 Day01]# /server/scripts/Day01/test.sh 
17. Usage: /server/scripts/Day01/test.sh {start|stop|status|restart|force-reload}
18. 
19. $n  n为数字 表示脚本的第n个参数 0被名称占用 所以从1开始
20. $1 为脚本第一个参数 $2 为脚本的第二个参数
21. [root@LB00 Day01]# cat test.sh
22. #!/bin/bash
23. echo $1 $2
24. [root@LB00 Day01]# sh test.sh name 20
25. name 20
26. [root@LB00 Day01]# cat test.sh
27. #!/bin/bash
28. echo $1 $2 ${10} ${11}
29. [root@LB00 Day01]# sh test.sh {a..z}
30. a b j k
31. 
32. $#  表示脚本传参的个数
33. [root@LB00 Day01]# cat test.sh
34. #!/bin/bash
35. echo $#
36. [root@LB00 Day01]# sh test.sh {a..z}
37. 26
38. 使用场景: 控制用户传参的个数
39. [root@LB00 Day01]# cat test.sh
40. #!/bin/bash
41. if [ $# -ne 2 ]
42. then
43.   echo "必须输入两个参数"
44. exit
45. fi
46. echo $1+$2|bc
47. [root@LB00 Day01]# sh test.sh 1 1
48. 2
49. 
50. $?  表示上一条命令的执行结果 0为成功 非0失败
51. 使用场景:
52. [root@LB00 Day01]# cat install.sh
53. #!/bin/bash
54. yum -y install wget &> /dev/null
55. [ $? -eq 0 ] && echo "wget安装成功" || echo "安装失败"
56. [root@LB00 Day01]# sh install.sh 
57. wget安装成功
58. 
59. [root@LB00 Day01]# cat ping.sh
60. #!/bin/bash
61. ping -c1 -W1 $1 &>/dev/null
62. [ $? -eq 0 ] && echo "$1 ping的通" || "$1 ping不通"
63. [root@LB00 Day01]# sh ping.sh www.baidu.com
64. www.baidu.com ping的通
65. 
66. $$  表示脚本的PID
67. [root@LB00 Day01]# cat test.sh    
68. #!/bin/bash
69. echo $$ > /tmp/nginx.pid    #方便到时候删除
70. 
71. $*  获取脚本的所有参数 在循环体中加双引号把所有的参数作为一个参数  
72. [root@LB00 Day01]# set -- "a b" c
73. [root@LB00 Day01]# echo $*
74. a b c
75. [root@LB00 Day01]# for i in $*;do echo $i;done
76. a
77. b
78. c
79. [root@LB00 Day01]# for i in "$*";do echo $i;done
80. a b c
81. 
82. $@  获取脚本的所有参数 在循环体中加上引号把所有的参数作为独立的参数
83. [root@LB00 Day01]# for i in "$@";do echo $i;done
84. a b
85. c
86. 
87. $_  表示获取执行脚本最后的一个值 类似esc .
88. 
89. 
90. -----重要
91. $0 表示脚本名称
92. $n 表示脚本传参的第n个参数
93. $# 表示传参的个数
94. $? 表示上一条命令的执行结果
95. 
96. ------了解
97. $$    脚本pid
98. $!    表示上一个后台任务(即通过&符号向后台提交的进程)的进程ID
99. $*    获取脚本的所有参数,在循环体中加双引号,把所有参数作为一个参数整体
100. $@    获取脚本的所有参数,在循环体中加双引号,所有参数都是独立的参数
101. $_    脚本中上一条命令的最后的参数,类似于esc .

六、变量三种传参方式

1. 第一种: 直接传参
2. [root@LB00 Day01]# cat test.sh
3. #!/bin/bash
4. echo name: $1
5. echo age: $2
6. [root@LB00 Day01]# sh test.sh koten 20
7. name: koten
8. age: 20
9. 
10. 第二种: 赋值传参
11. [root@LB00 Day01]# cat test.sh
12. #!/bin/bash
13. name=$1
14. age=$2
15. echo name: $name
16. echo age: $age
17. [root@LB00 Day01]# sh test.sh koten 20
18. name: koten
19. age: 20
20. 
21. 第三种: read读入,交互式
22. [root@LB00 Day01]# cat test.sh 
23. #!/bin/bash
24. read -p "请您输入姓名:" name
25. read -p "请您输入年龄:" age  
26. echo 姓名: $name
27. echo 年龄: $age
28. [root@LB00 Day01]# sh test.sh
29. 请您输入姓名:koten
30. 请您输入年龄:20
31. 姓名: koten
32. 年龄: 20

扩展

需求:使用三种传参方式,修改主机名称和IP地址,修改完IP,输出修改的结果到屏幕,在重启网络

一、直接传参

1. [root@LB00 Day01]# cat change.sh
2. #!/bin/bash
3. hostnamectl set-hostname --static $1
4. sed -i 's#IPADDR.*#IPADDR='$2'#g' /etc/sysconfig/network-scripts/ifcfg-eth0
5. systemctl restart network
6. [root@LB00 Day01]# sh change.sh LB00 10.0.0.4
7. [root@LB00 Day01]# hostname
8. LB00
9. [root@LB00 Day01]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
10. TYPE=Ethernet
11. BOOTPROTO=none
12. NAME=eth0
13. DEVICE=eth0
14. ONBOOT=yes
15. IPADDR=10.0.0.4
16. PREFIX=24
17. GATEWAY=10.0.0.2
18. DNS1=223.5.5.5

二、赋值传参

1. [root@LB00 Day01]# cat change.sh
2. #!/bin/bash
3. hostname=$1
4. ip=$2
5. hostnamectl set-hostname --static $hostname
6. sed -i 's#IPADDR.*#IPADDR='$ip'#g' /etc/sysconfig/network-scripts/ifcfg-eth0
7. systemctl restart network

三、read交互式传参

1. [root@LB00 Day01]# cat change.sh 
2. #!/bin/bash
3. read -p "请输入要修改的主机名:" hostname
4. read -p "请输入要修改的ip:" ip
5. hostnamectl set-hostname --static $hostname
6. sed -i 's#IPADDR.*#IPADDR='$ip'#g' /etc/sysconfig/network-scripts/ifcfg-eth0
7. systemctl restart network
8. [root@LB00 Day01]# sh change.sh 
9. 请输入要修改的主机名:LB0
10. 请输入要修改的ip:10.0.0.3
11. 
12. #因为修改了ip,Xshell断开了


我是koten,10年运维经验,持续分享运维干货,感谢大家的阅读和关注!

目录
相关文章
|
4天前
|
运维 Devops
自动化运维:从脚本到DevOps的进化之旅
在数字化时代,自动化运维不仅是提高生产效率的关键,更是企业竞争力的象征。本文将带领读者穿越自动化运维的发展历程,从最初的脚本编写到现代DevOps文化的形成,揭示这一演变如何重塑IT行业的工作模式。通过具体案例,我们将展示自动化工具和实践如何简化复杂任务,优化流程,并促进团队协作。你将发现,自动化运维不仅关乎技术的进步,更体现了人、流程和技术三者之间协同增效的深层逻辑。
|
18天前
|
运维 监控 Python
自动化运维:使用Python脚本简化日常任务
【10月更文挑战第36天】在数字化时代,运维工作的效率和准确性成为企业竞争力的关键。本文将介绍如何通过编写Python脚本来自动化日常的运维任务,不仅提高工作效率,还能降低人为错误的风险。从基础的文件操作到进阶的网络管理,我们将一步步展示Python在自动化运维中的应用,并分享实用的代码示例,帮助读者快速掌握自动化运维的核心技能。
33 3
|
23天前
|
缓存 运维 NoSQL
python常见运维脚本_Python运维常用脚本
python常见运维脚本_Python运维常用脚本
25 3
|
24天前
|
运维 监控 应用服务中间件
自动化运维:如何利用Python脚本提升工作效率
【10月更文挑战第30天】在快节奏的IT行业中,自动化运维已成为提升工作效率和减少人为错误的关键技术。本文将介绍如何使用Python编写简单的自动化脚本,以实现日常运维任务的自动化。通过实际案例,我们将展示如何用Python脚本简化服务器管理、批量配置更新以及监控系统性能等任务。文章不仅提供代码示例,还将深入探讨自动化运维背后的理念,帮助读者理解并应用这一技术来优化他们的工作流程。
|
25天前
|
运维 监控 Linux
自动化运维:如何利用Python脚本优化日常任务##
【10月更文挑战第29天】在现代IT运维中,自动化已成为提升效率、减少人为错误的关键技术。本文将介绍如何通过Python脚本来简化和自动化日常的运维任务,从而让运维人员能够专注于更高层次的工作。从备份管理到系统监控,再到日志分析,我们将一步步展示如何编写实用的Python脚本来处理这些任务。 ##
|
29天前
|
运维 Prometheus 监控
自动化运维之路:从脚本到DevOps
【10月更文挑战第25天】在数字化时代的浪潮中,运维不再是简单的服务器管理,而是成为了企业竞争力的核心。本文将带你走进自动化运维的世界,探索如何通过技术手段提升效率和稳定性,以及实现快速响应市场的能力。我们将一起学习如何从基础的脚本编写进化到全面的DevOps实践,包括工具的选择、流程的优化以及文化的建设。无论你是运维新手还是资深专家,这篇文章都将为你提供有价值的见解和实用的技巧。
29 3
|
2月前
|
人工智能 运维 Devops
自动化运维之路:从脚本到DevOps的转变
【10月更文挑战第7天】在这篇文章中,我们将一起探索自动化运维的演变历程,从最初的简单脚本到现代的DevOps实践。我们将深入理解自动化如何改变了运维工作的本质,并讨论实现这一转变的关键技术和策略。文章将不包含代码示例,而是聚焦于理念、工具和方法论的介绍,旨在为读者提供一个全面的自动化运维框架视图。
|
2月前
|
运维 Java Linux
【运维基础知识】Linux服务器下手写启停Java程序脚本start.sh stop.sh及详细说明
### 启动Java程序脚本 `start.sh` 此脚本用于启动一个Java程序,设置JVM字符集为GBK,最大堆内存为3000M,并将程序的日志输出到`output.log`文件中,同时在后台运行。 ### 停止Java程序脚本 `stop.sh` 此脚本用于停止指定名称的服务(如`QuoteServer`),通过查找并终止该服务的Java进程,输出操作结果以确认是否成功。
45 1
|
2月前
|
人工智能 运维 监控
自动化运维:从脚本到工具的演变之路
【10月更文挑战第8天】在数字化时代的浪潮中,运维不再是简单的硬件维护,它已经演变成一场关于效率、稳定性和创新的技术革命。本文将带您领略自动化运维的魅力,从最初的脚本编写到现代复杂的自动化工具,我们将一探究竟,看看这些工具如何帮助运维人员简化日常任务,提升工作效率,并最终推动业务发展。
|
2月前
|
存储 运维 监控
自动化运维:使用Shell脚本简化日常任务
【9月更文挑战第35天】在IT运维的日常工作中,重复性的任务往往消耗大量的时间。本文将介绍如何通过编写简单的Shell脚本来自动化这些日常任务,从而提升效率。我们将一起探索Shell脚本的基础语法,并通过实际案例展示如何应用这些知识来创建有用的自动化工具。无论你是新手还是有一定经验的运维人员,这篇文章都会为你提供新的视角和技巧,让你的工作更加轻松。
66 2