【运维知识高级篇】超详细的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年运维经验,持续分享运维干货,感谢大家的阅读和关注!

目录
相关文章
|
1月前
|
存储 Java Shell
Shell 变量
10月更文挑战第2天
25 0
|
1月前
|
存储 运维 监控
自动化运维:使用Shell脚本简化日常任务
【9月更文挑战第35天】在IT运维的日常工作中,重复性的任务往往消耗大量的时间。本文将介绍如何通过编写简单的Shell脚本来自动化这些日常任务,从而提升效率。我们将一起探索Shell脚本的基础语法,并通过实际案例展示如何应用这些知识来创建有用的自动化工具。无论你是新手还是有一定经验的运维人员,这篇文章都会为你提供新的视角和技巧,让你的工作更加轻松。
53 2
|
2月前
|
Shell
shell脚本变量 $name ${name}啥区别
shell脚本变量 $name ${name}啥区别
|
2月前
|
Java Shell Linux
Shell 变量设置
Shell设置变量
44 5
|
2月前
|
Java Shell Linux
Shell 变量设置25-1
Shell编程语言是一种非类型的解释型语言,无需像C++/Java那样事先声明变量。通过赋值即可定义变量,在Linux支持的所有Shell中均适用。变量分为局部变量与环境变量,前者仅限于定义脚本内使用,后者可在其派生的子进程中使用。常见系统变量如$0表示当前程序名称,$n表示第n个参数(n=1,2,...,9),$*代表所有参数,$#代表参数个数,$?表示命令执行后的状态(0为成功),$UID为当前用户ID,$PWD表示当前目录。定义变量如`A=123`,
30 0
|
3月前
|
Shell
[shell]在curl测试的data参数中引用变量
[shell]在curl测试的data参数中引用变量
204 1
|
3月前
|
运维 监控 Shell
自动化运维之宝:编写高效的Shell脚本
【8月更文挑战第31天】在运维的世界里,Shell脚本是一把瑞士军刀,它让日常任务变得简单而高效。本文将通过浅显易懂的语言和实际案例,带你领略Shell脚本的魅力,并教你如何打造属于自己的自动化工具箱。无论你是初学者还是资深运维,这篇文章都将为你打开一扇窗,让你看到不一样的风景。让我们一起探索Shell脚本的世界吧!
|
4月前
|
分布式计算 大数据 Shell
MaxCompute产品使用合集之odps shell如何将ech变量的结果集合写入文件,并且指定服务器的位置
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
45 10
|
1月前
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
75 1
|
20天前
|
Shell Linux 测试技术
6种方法打造出色的Shell脚本
6种方法打造出色的Shell脚本
42 2
6种方法打造出色的Shell脚本