【运维】Shell脚本学习
0、随笔概述
1、个人笔记
多理解别人的脚本怎么写的,先看别人的脚本。
伪代码
先写中文思路,
然后写好了,检查脚本,
检查好了再运行。
书写脚本的习惯很重要。
脚本第一行为命令解释器,如#!bin/bash
#!/bin/bash
#!/bin/python
#!/bin/awk
#!/bin/sed
不同角色使用shell脚本:
- Linux运维工程师:服务器集群管理,使用Shell脚本更加方便
- 开发工程师:领导要求编写脚本进行程序或服务器的维护,如定时备份数据库
- 大数据工程师:编写shell脚本管理集群
shell介绍:
- shell是命令解释器,也可以叫bash高级编程,用户编写shell脚本之后,shell运行脚本调用内核控制系统及硬件,如启动、停止服务器。
2、前置知识
shell脚本格式要求:
- 脚本以
#!/bin/bash
开头 - 脚本需要有可执行权限
编写第一个shell脚本
- 创建一个shell脚本,输出hello world!
#!/bin/bash
echo "hello world!"
四种执行shell脚本
- 输入脚本的绝对路径或想对路径
1、首先赋予脚本需要执行此脚本用户的可执行权限(chmod 744 脚本名
)
2、绝对路径或相对路径执行此脚本(./脚本名
) - 使用命令解释器(
sh、bash
)来执行脚本
0、使用此方式无需赋可执行权限,直接执行即可。
1、如:sh 脚本名.sh
,bash 脚本名.sh
- 特殊执行脚本的方式:
source ./脚本名
或者.(点) ./脚本名
1、使用场景:让环境变量生效:source或者(点) /etc/profile /etc/bashrc ~/.bashrc
2、类似于include功能:防止配置文件太多,放在其他位置的配置文件包含到主配置文件中
#!/bin/bash
#引入functions文件
source /etc/init.d/functions
#输出web服务状态
action "web is ok" /bin/true
echo "web is ok!"
- 输入重定向
sh < check_web.sh
方法 | 应用场景 | 注意事项 |
---|---|---|
sh或bash | 各种场景均有使用,必会 | |
脚本加上x权限 | 系统脚本中使用时,需要拥有x权限 | |
source或者(.)点 | 1、让环境变量生效 2、实现文件包含(include) |
|
输入重定向方法(<) | 几乎不用, |
Shell变量的定义:
-
基本语法:
1、定义变量:变量=值
2、撤销变量:unset 变量
3、声明静态变量:readonly 变量。此类变量不能unset。 -
快速入门:
1、定义变量A
2、撤销变量A
3、声名静态变量B=2,不能unset
4、可把变量提升为全局环境变量,可供其他shell程序使用
#!/bin/bash
A=100
echo "A=$A"
unset A
echo "A=$A"
#!/bin/bash
readonly A=90
echo "A=$A"
unset A
echo "A=$A"
1、编写Shell脚本中优良的习惯
- 首行加上命令解释器
- 版权说明,谁在什么时间写的,该脚本主要作用
- 编写脚本尽量不要使用中文,遇到“跑机房”情况容易中文乱码
- 成对的符号,提前敲好
"" '' `` [] () {}
- 脚本文件名尽量不要包含服务名称,如检查nginx的脚本,尽量不要使用nginx.sh,容易歧义,脚本名称尽量见名知意。
2、Shell中的变量
2.1、什么是变量
- 可以变化的量,用固定字符(英文)替代更多复杂的内容。
- 存放在脚本中经常用到的内容,如:ip 时间
ip=192.168.123.1
- 变量的本质是内存中的一个区域,通过变量名称的地址找到变量并操作
Shell的变量的介绍:
1、linux shell变量分为两种(系统变量、用户自定义变量)。
2、系统变量:系统定义好的,直接用$HOME、$PSD、$SHELL、$USER
,如:echo $HOME
3、显示当前shell中所有变量:set
[shine@shine00 shellScript]$ echo "环境变量:"$PATH "当前登陆用户:"$USER
环境变量:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/shine/.local/bin:/home/shine/bin 当前登陆用户:shine
2.2、变量的命名规则
1、变量名称可由字母、数字、下划线组成,但不能以数字开头。
2、等号两侧不能有空格
3、变量名称一般为大写
4、见名知意,定义变量,知道是要干啥的
5、驼峰命名规则
6、下划线命名规则(建议用这)
7、变量表示作用
将命令的返回值(结果)复制给变量
1、A=ls-la
反引号,运行里面的命令,并把结果返回给变量A
2、A=$(ls-la)等价于反引号
3、中文字符不建议使用''单引号,尽量使用""双引号
#!/bin/bash
RESULT=`ls -l /home`
echo RESULT
echo '================'
MY_DATE=$(date)
echo 'date=$MY_DATE'
2.3、变量的分类
- 环境变量(全局变量)系统自动创建 blobal var user
- 普通变量(局部变量)脚本中自定义的变量
- 特殊变量(高级操作,10个左右)匹配脚本参数,服务状态,特殊替换
3、实践操作
Shell脚本分析
#!/bin/sh
#定义变量其值为Shell本身的文件名
PRG="$0"
#定义变量dPRGDIR的值为dirname加上Shell本身文件名
PRGDIR=`dirname "$PRG"`
#定义变量APP_HOME的值为 cd Shell本身文件名下的文件,并输出当前目录
APP_HOME=`cd "$PRGDIR/.." ; pwd`
#执行APP_HOME下bin目录下setenv.sh文件
. ${APP_HOME}/bin/setenv.sh
#定义变量KEY_SUFFIX文件为空
KEY_SUFFIX=""
#定义变量path的值为当前Shell脚本的父路径下的resource路径。
path=$(dirname "$PWD")/resources/
#定义变量files的值为path(resource)下所有文件名
files=$(ls $path)
#遍历files中的内容给filename
for filename in $files
do
#如果
if [ "${filename##*.}"x = "jar"x ];then
#那么这就是jar包的位置
KEY_SUFFIX=${filename%.jar}
fi
done
#输出jar包的目录
echo $KEY_SUFFIX
#定义变量PRO_KEY的值为jar包的名称
PRO_KEY=Cloud:name_${KEY_SUFFIX}
#定义变量MAIN_JAR为当前为上个
MAIN_JAR="../resources/${KEY_SUFFIX}.jar"
#定义变量PRO_COUNT为当前jar包脚本检查命令
PRO_COUNT=`ps -ef |grep ${PRO_KEY} | grep -v grep | wc -l`
#如果变量PRO_COUNT小于1(jar包没启动)的话
if [ ${PRO_COUNT} -lt 1 ]
then
#nohub在后台一直使用参数运行此jar包
#启动的时候使用参数jvm调优-Xms初始队大小-Xmx最大堆大小
nohup java -Xms100m -Xmx512m -XX:PermSize=100M -XX:MaxPermSize=512m -D${PRO_KEY} -jar ${MAIN_JAR} --spring.config.location=${APP_HOME}/resources/bootstrap.yml,${APP_HOME}/resources/application.yml > /dev/null 2>&1 &
echo "${PRO_KEY} started!"
else
#否则的话,提示jar包已启动
echo "there is already ${PRO_COUNT} process with key ${PRO_KEY} exists"
fi
JVM调优参数
JVM调优参数
[monitor@ln-restore ~]$ java -X
-Xmixed 混合模式执行 (默认)
-Xint 仅解释模式执行
-Xbootclasspath:<用 : 分隔的目录和 zip/jar 文件>
设置搜索路径以引导类和资源
-Xbootclasspath/a:<用 : 分隔的目录和 zip/jar 文件>
附加在引导类路径末尾
-Xbootclasspath/p:<用 : 分隔的目录和 zip/jar 文件>
置于引导类路径之前
-Xdiag 显示附加诊断消息
-Xnoclassgc 禁用类垃圾收集
-Xincgc 启用增量垃圾收集
-Xloggc:<file> 将 GC 状态记录在文件中 (带时间戳)
-Xbatch 禁用后台编译
-Xms<size> 设置初始 Java 堆大小
-Xmx<size> 设置最大 Java 堆大小
-Xss<size> 设置 Java 线程堆栈大小
-Xprof 输出 cpu 配置文件数据
-Xfuture 启用最严格的检查, 预期将来的默认值
-Xrs 减少 Java/VM 对操作系统信号的使用 (请参阅文档)
-Xcheck:jni 对 JNI 函数执行其他检查
-Xshare:off 不尝试使用共享类数据
-Xshare:auto 在可能的情况下使用共享类数据 (默认)
-Xshare:on 要求使用共享类数据, 否则将失败。
-XshowSettings 显示所有设置并继续
-XshowSettings:all
显示所有设置并继续
-XshowSettings:vm 显示所有与 vm 相关的设置并继续
-XshowSettings:properties
显示所有属性设置并继续
-XshowSettings:locale
显示所有与区域设置相关的设置并继续
-X 选项是非标准选项, 如有更改, 恕不另行通知。
JVM调优参数2
JVM按照其存储数据的内容将所需内存分配为堆区与非堆区两个部分:
所谓堆区即为通过new的方式创建的对象(类实例)所占用的内存空间;
非堆区即为代码、常量、外部访问(如文件访问流所占资源)等。
然而虽然java的垃圾回收机制虽然能够很好的解决内存浪费的问题,
但是这种机制也仅仅的是回收堆区的资源,而对于非堆区的资源就束手无策了,
针对这样的资源回收只能凭借开发人员自身的约束来解决。
-Xms
#指设定程序启动时占用内存大小。(堆区配置)
一般来说,启动时占用的内存大点程序会启动得快一点,但是也可能导致机器暂时变慢。
通常为操作系统可用内存的1/64大小即可,但仍需按照实际情况进行分配。
-Xmx
#指设定程序运行期间最大可以占用的内存大小。(堆区配置)
如果程序运行需要占用更多的内存,超出了这个设置的值,就会抛出OutOfMemory异常。
通常为操作系统可用内存的1/4大小。
##通常会将 -Xms 和 —Xmx两个参数的配置相同的值,
其目的是为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小,
从而提高性能。
##JVM中最大堆大小有三方面的限制:
(1)相关操作系统的数据模型(32-bit 还是 64-bit)限制;
(2)系统的可用虚拟内存限制;
(3)系统可用物理内存限制。
32位系统下,一般限制在1.5~2G,64位操作系统对内存无限制。
-XX:PermSize
#指非堆区初始化内存分配大小。(非堆区配置)
-XX:MaxPermSize
#指对非堆区分配内存的最大上限。(非堆区配置)
##在配置之前,一定要慎重的考虑一下软件所需的非堆区内存的大小,
因为此处内存是不会被java垃圾回收机制进行处理的地方。
并且更加要注意的是:最大堆内存与最大非堆内存的和绝对不能够超出操作系统的可用内存。
参考:
1、tomcat中关于-Xms -Xmx -XX:PermSize -XX:MaxPermSize的理解和区别 - CSDN博客
https://blog.csdn.net/hsj1213522415/article/details/56494973
2、JVM调优总结 -Xms -Xmx -Xmn -Xss - CSDN博客
https://blog.csdn.net/rickyit/article/details/53895060
3、tomcat的内存配置,关于-Xms -Xmx -XX:PermSize -XX:MaxPermSize的理解和区别 - 范远 - 博客园
https://www.cnblogs.com/fan-yuan/p/7238429.html
————————————————
版权声明:本文为CSDN博主「思想流浪者」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_30346413/article/details/80672710
4、学习总结
5、参考资料
菜鸟教程Shell脚本学习:https://www.runoob.com/linux/linux-shell.html
菜鸟教程Shell在线工具:https://www.runoob.com/try/runcode.php?filename=helloworld&type=bash
## 5.1、哔哩哔哩嵌入代码引用
<div style="position: relative; padding: 40% 45%;"><iframe src="//player.bilibili.com/player.html?aid=21303002&bvid=BV1dW411M7xL&cid=35073881&page=58" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" style="position: absolute; width: 100%; height: 100%; left: 0; top: 0;"></iframe></div>