Mac m2自动登陆跳板机脚本
需求需求很简单,通过脚本自动登陆跳板机。因为最近换的是mac M2,然后碰到了一堆问题。
问题从intel芯片换到m2出现很多问题。首先mac m2 没有python2,默认是python3,所以脚本的命令要调整成python3相关的。然后是 ssh 登陆,原来正常可以登陆方式也有问题,默认的ssh密钥失效,需要替换成新的密钥。就导致原来的免密登陆也失效了,添加了公钥,依然需要输密码,下面的脚本,有一段是补偿输入密码的操作,如果不需要,可以删了输密码的部份。
自动登陆脚本需要准备两个脚本:
login.sh, shell 脚本
jump.python, python3脚本
1234567891011121314#!/bin/shexpect -c "set pwd you_pass_wordspawn ssh -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa test@10.10.10.10set timeout 2expect "*assword:*"send \&quo ...
shell 错误日志告警脚本
背景服务器有敏感数据,不允许直接登陆服务器查看日志文件,也不允许使用如ELK等日志功能收集日志,所以只能使用最简单的办法,只将错误日志进行收集,然后通过应用的webhook进行收集。
思路两种思路:
周期轮询
实时抓取
周期轮询每隔一分钟去抓取一次,错误日志的内容上送webhook。这样的好处是不会抓到过多的错误日志,但是也有个问题,有可能会错过关键的错误日志。假如每一分钟一轮询,这一次查询刚好没有错误日志产生,而这一个轮询时刻的一分钟内产生了错误日志,就会错过。
如果到到轮询时刻去统计这一分钟到上一分钟之间的错误日志,是可以,但是如果错误在轮询完成后的这一刻发生,需要等到一分钟之后才会告警出来,缺乏实时性,如果对实时性要求不高可以使用这种方式。
实时抓取这个思路很简单,就是实时抓取ERROR日志,有ERROR就推送webhook。实现思路:
使用 tail 查询日志
倒序获取第一条
关键字可指定
过滤关键字
下面这个脚本实现以上的几个思路,算是一种简单的实现,我一直觉得脚本这东西不要写的太复杂,需要考虑后面的人维护的成本。另外脚本尽量使用python而不是shell,pyth ...
shell判空true false的一个坑
前言在写shell的时候发现一个违反直觉的的操作,一般判断一个变量是否为boolean,习惯上使用if param。但是在写脚本的时候,发现无论如何,不会走false。
反例在很多编程语言中,可以直接使用 if boolean,来判断这个变量是否为true。但是在shell当中直觉上是可以,但实际上是不能。
123456aaa=falseif [[ $aaa ]];then echo "is true"else echo "is false"fi
结是为is true,是不是违反直觉。
为什么这段脚本会进is true。
shell 是怎么执行这一段脚本的:
1sh -x test.sh
结果:
1234+ aaa=false+ [[ -n false ]]+ echo 'is true'is true
可以看到,如果是一个变量,shell 会默认加上-n来判断变量是否为空。aaa是有值的,而且在shell里,false 并不代表false。真正代表true和false的是0和1,没想到吧。
正常判断注意,这里用的是 ...
shell-判断奇偶数
前言不能直接除2的就不是偶数,比较简单。
123456789101112131415161718192021#!/bin/bashdataArr=(012345678910)for i in ${!dataArr[@]}do if [[ $(($i%2)) = 0 ]]; then echo "index: $i, data: ${dataArr[$i]}" fidone
结果:index: 0, data: 0index: 2, data: 2index: 4, data: 4index: 6, data: 6index: 8, data: 8index: 10, data: 10
需要注意的是,$(($i%2)) = 0 等号中间是有空格的,不能连着写,否则结果不正确。这可真是垃圾的设计!!
shell 数组
shell 也支持数组,就是写法跟平时的开发语言不太一样,反正我是觉得挺别扭。
声明数组数组数据使用一对括号( var )包起来,就能成为数组。
1234arr=(10 20 30 40)echo $arrecho $arr[1]echo $arr[2]
结果:
1020
打印数组打印数组的话要注意,直接打印数组,只会打印出第一条数数据,必须加上* 或 #,才能全部输出。
12345678910111213141516171819#!/bin/bash#数组取值days=(one two three 4)echo ${days}echo ${days[0]}echo ${days[1]}echo ${days[@]}echo ${days[*]}echo "**********"# 重置数组names=()names[1]=tomnames[2]=jackecho ${names}echo ${names[1]}echo ...
shell 保持gc.log文件个数
摘要使用JDK8的老项目,开启了gc log用于排查问题,但是每次重启总是会覆盖之前的gc log,所以写了一个脚本保存gc log。如果是JDK11直接使用xlog,就可以配置很详细的日志策略。能起到一个什么效果,就是控制文件的个数。
脚本说明:maxFile: 允许最大文件个数currentDirCount: 当前目录包含多少日志文件oldFileSize: 需要清理的老文件数量ls -1: 升序排序,排时间较早的文件排列
123456789101112131415161718192021222324252627#!/bin/bashmaxFile=5gcLogDir=logs/gc_logs/echo 'backup gc.log'if [ ! -d "$gcLogDir" ];then mkdir -p 'logs/gc_logs'fiif [ -f 'gc.log' ]; then dateformat=`date "+%Y-%m-%d_%H-%M-%S"` tar -c ...
shell 删除目录下备份目录数量
前言经常需要通过脚本来控制系统目录的里备份文件数量。不可能手动来经常查看,总是忘记。通过脚本定期自己查看目录里的文件数据,删除时间较早的目录。
实现那么就要设置几个条件:
允许存在几个目录
超过了怎么删除
怎么判断目录下有多少个目录?用ls就可以。
那多出来的怎么删除?遍历删,直到没有为止
完整代码如下:
1234567891011#!/bin/bashdirCount=5# 查看当前目录数currentDirCount=`ls -l | grep "^d" | wc -l`# 遍历删,直到没有为止while [ $currentDirCount -gt $dirCount ]do rm -rf `ls -1|head -n 1` currentDirCount=`ls -l | grep "^d" | wc -l`done
过滤目录,d 表示目录
grep "^d"
制造一些测试数据,然后执行上面的脚本验证。
1mkdir test1 test2 test3
最后一个问题,什么时候来执行呢?这个就看具体的策略 ...
shell--解决数组拼接变成一行
问题碰到了一个奇怪的问题,脚本在执行推送数据任务的时候,总是会有两个节点是失败的,确认环境都是相关的,有可能是脚本有毛病,加了堆日志后发现确实有问题。因为之前修改数组拼接的方法。
出现问题的shell123456789101112131415161718192021222324#!/usr/bin/bashdevNet=(10.40.100.11410.40.100.115)testNet=(#10.40.100.11110.40.100.110)testFn() { local nodes=("$@") for node in "${nodes[@]}"; do echo "[info]: restart node: $node" done}# 就因为用 " " 包起来了所以就出问题了,把两行当成一行处理allNode=("${devNet[@]} ${testNet[@]}")testFn & ...
shell--ssh解析本地变量到远程失败
问题很多问题都是由于双眼号引起的,但是shell标准确很喜欢让开发者加上双眼号。脚本通过ssh远程操作其它相器,正常情况下脚本会将我本机的脚本变量带到远程机器上,这个脚本一直远行正常。然后看到一个shell的变量使用规范,要在大部分重要的变量是加上又眼号,我就这么干了,然后就出问题了。
正常场景我在本机:192.168.1.100上执行脚本,并登陆:192.168.1.200上操作一下,正常应该打印出:test-abcd,但是由于变量失效,则打印为空。
123456789101112131415161718192021222324#!/bin/bashnodes(192.168.1.101192.168.1.102192.168.1.200)myVar="test-abcd"startNodes() { local nodes=("$@") for node in "${nodes[@]}"; do { echo "[info]: start node: $ ...
shell 实现一个下载脚本
前言在写复杂脚本时,往往需要复用下载这个操作,刚好碰到这个问题,就把下载功能抽成一个函数,拿来复用。
实现实现就比较简单了,直接上代码,这段代码复制就可以直接使用。功能上判断一下当前系统中使用的的wget还是curl,选择其中一个工具进行下载。
12345678910111213141516171819202122#!/bin/bashdownload() { local url=$1 local file_name=$2 if type wget >/dev/null 2>&1; then wget --no-check-certificate -q $url elif type curl >/dev/null 2>&1; then echo "curl -OLJ $url" curl -OLJ $url else echo 'info: no exists wget or curl, make sure the system can use the "wget ...