​jq​

​jq​ 是一个命令行的 JSON 处理器。

  • 云服务 API:AWS, Azure, Google Cloud 的 CLI 工具返回的都是 JSON。
  • 监控告警:Prometheus, Zabbix, Grafana 发送的告警通知是 JSON。
  • 容器编排:Kubernetes API 返回的资源状态是 JSON。
  • CI/CD 工具:Jenkins, GitLab 的 API 交互也是 JSON。
  • 结构化日志:越来越多的应用采用 JSON 格式记录日志,便于机器解析。

​jq​ 解决了这个根本问题:它能“理解”JSON 的结构,通过键(key)来精确、可靠地提取、修改和重组数据。

jq​ 的核心功能演示

csp='{"Host_name":"192.168.xxx.xxx","Host_IP":"192.168.xxx.xxx","Time":"2020-10-15 11:00:00","Severity":"Average","Information":"MySQL: Server has aborted connections (over 3 for 5m)","Porject":"mysql.aborted_connects.rate","Detals":"Connections: Aborted connections per second:0","Status":"PROBLEM:8.858728","Original problem ID":"202010151105"}'

1. 格式化和高亮(最常用)

这是 jq​ 的“Hello, World!”。把混乱的单行 JSON 格式化为可读的多行形式。
​.​ (点号) 表示“整个输入对象”。

echo "$csp" | jq '.'

输出:

{
  "Host_name": "192.168.xxx.xxx",
  "Host_IP": "192.168.xxx.xxx",
  "Time": "2020-10-15 11:00:00",
  "Severity": "Average",
  "Information": "MySQL: Server has aborted connections (over 3 for 5m)",
  "Porject": "mysql.aborted_connects.rate",
  "Detals": "Connections: Aborted connections per second:0",
  "Status": "PROBLEM:8.858728",
  "Original problem ID": "202010151105"
}

2. 提取字段值

使用 .key​ 语法来获取特定字段的值。

# 获取告警信息
echo "$csp" | jq '.Information'
# 输出: "MySQL: Server has aborted connections (over 3 for 5m)"

# 如果不想要外面的双引号,使用 -r (raw output) 选项
echo "$csp" | jq -r '.Information'
# 输出: MySQL: Server has aborted connections (over 3 for 5m)

3. 提取多个字段并构建新对象

您可以选择几个字段,重新组合成一个新的 JSON 对象。

echo "$csp" | jq '{ip: .Host_IP, status: .Status, info: .Information}'
输出:
{
  "ip": "192.168.xxx.xxx",
  "status": "PROBLEM:8.858728",
  "info": "MySQL: Server has aborted connections (over 3 for 5m)"
}

4. 修改或添加字段(解决您的问题)

这正是我们之前讨论的,可以轻松地添加一个新字段。

echo "$csp" | jq '. + {CLEA: 1}'

输出(部分):

{
  ...
  "Original problem ID": "202010151105",
  "CLEA": 1  # <-- 新增的字段
}

5. 结合 Shell 脚本使用

​jq​ 的输出可以轻松赋值给 Shell 变量,让脚本处理逻辑变得清晰可靠。

# 从告警中提取 IP 地址和状态
HOST_IP=$(echo "$csp" | jq -r '.Host_IP')
STATUS=$(echo "$csp" | jq -r '.Status')

echo "告警来自 IP: $HOST_IP,当前状态是: $STATUS"
# 输出: 告警来自 IP: 192.168.xxx.xxx,当前状态是: PROBLEM:8.858728

总结

黄金法则:不要用正则表达式或 cut​/awk​ 来解析 JSON。请使用 jq​。

豆包代写的代码

import requests
import json
import sys

url = 'http://x.x.x.x/v1/chat-messages'
headers = {
  'Authorization': 'Bearer app-KT4yNocX6Bzey6mZ5Jxxxx',
    'Content-Type': 'application/json'
}
conversation_id = ""

while True:
    try:
        # 获取系统默认编码
        encoding = sys.getdefaultencoding()
        query = input("请输入你的问题(输入 '退出' 结束对话):").encode(encoding).decode(encoding)
        if query == "退出":
            break

        data = {
            "inputs": {},
            "query": query,
            "response_mode": "streaming",
            "conversation_id": conversation_id,
            "user": "ts",
            "files": [
                {
                    "type": "image",
                    "transfer_method": "remote_url",
                    "url": "https://cloud.dify.ai/logo/logo-site.png"
                }
            ]
        }

        try:
            response = requests.post(url, headers=headers, json=data, stream=True)
            response.raise_for_status()

            full_response = []
            full_api_response = []
            for chunk in response.iter_lines(decode_unicode=True):
                if chunk.startswith('data:'):
                    chunk_data = chunk[5:].strip()
                    if chunk_data:
                        full_api_response.append(chunk_data)
                        try:
                            event = json.loads(chunk_data)
                            if event.get('event') == 'message':
                                answer = event.get('answer', '')
                                print(answer, end='', flush=True)
                                full_response.append(answer)
                            elif event.get('event') == 'message_end':
                                print()
                                final_answer = ''.join(full_response)
                                print(f"完整回复: {final_answer}")
                                conversation_id = event.get('conversation_id', conversation_id)
                        except json.JSONDecodeError:
                            print(f"解析错误: {chunk_data}")
            print("\nAPI 接口返回的完整信息:")
            for line in full_api_response:
                print(line)

        except requests.exceptions.RequestException as e:
            print(f"请求错误: {e}")
    except UnicodeDecodeError:
        print("输入解码时出现错误,请检查终端编码设置。")

ansible-playbook 被管理主机网络测试


  • name: Test connectivity to 61.139.2.69:80 from managed hosts
    hosts: all # 测试被管理主机的连通性
    gather_facts: no # 不需要收集主机信息以加快执行速度
    tasks:
    • name: Wait for port 80 on 61.139.2.69 to become reachable
      wait_for:
      host: 61.139.2.69
      port: 80
      timeout: 10 # 超时时间为10秒
      ignore_errors: yes
      register: port_status
    • name: Report connectivity status
      debug:
      msg: >
      {{ ‘Connectivity to 61.139.2.69:80 is reachable’ if port_status.state == ‘started’
      else ‘Connectivity to 61.139.2.69:80 is not reachable’ }}

写代码的准备工作

在Windows 11上写代码的几个方面的准备:

  1. 安装Java开发工具包(JDK):确保你已经安装了适用于Windows 11的Java开发工具包(JDK)。
  2. 选择集成开发环境(IDE):选择一个适合你的喜好和需求的Java集成开发环境(IDE),如Eclipse、IntelliJ IDEA或NetBeans。下载并安装你选择的IDE,并根据需要进行配置和插件安装。
  3. 设置环境变量:在Windows 11上,你需要设置Java的环境变量,以便系统能够找到JDK和其他相关工具。将JDK的安装路径添加到系统的PATH环境变量中,以便在命令行中可以直接访问Java和相关工具。
  4. 安装版本控制工具:考虑安装一个版本控制工具,如Git,以便你可以管理和跟踪代码的版本和变更。下载并安装Git,并配置你的Git账户信息。
  5. 选择文本编辑器:除了IDE,你可能还需要一个文本编辑器来编辑和查看代码文件。Windows 11上有许多文本编辑器可供选择,如Notepad++、Sublime Text、Visual Studio Code等。选择一个适合你的需求和偏好的文本编辑器,并进行安装和配置。
  6. 安装必要的开发工具和库:根据你的项目需求,可能需要安装其他开发工具和库。例如,如果你使用Maven或Gradle进行项目构建和依赖管理,你需要安装并配置相应的工具。
  7. 配置开发环境:根据你的项目需求,配置你的开发环境。这可能包括设置数据库连接、配置服务器环境、安装必要的插件和扩展等。

python遍历文件数

import sys
import os

count = 0

# 遍历文件夹
def walkFile(file):
    for root, dirs, files in os.walk(file):
        # root 表示当前正在访问的文件夹路径
        # dirs 表示该文件夹下的子目录名list
        # files 表示该文件夹下的文件list

        # 遍历文件
        for f in files:
            global count
            count += 1
            #print(os.path.join(root, f))
            os.path.join(root, f)

        # 遍历所有的文件夹
        for d in dirs:
            #print(os.path.join(root, d))
            os.path.join(root, d)
    print("文件数量一共为:", count)

if __name__ == '__main__':
    walkFile(r"/data/dfs/data/")
	
开始时间: 1636442653.8381789
此次分析的目录: /data/dfs/data/
文件数量一共为: 87416186
结束时间: 1636444145.756604
计算时间: 1491.9184250831604

[root@host-40 scripts]# python3 test.py 
文件数量一共为: 87423691

chrome面板

请求列表
Name:资源名称
Status:HTTP状态码
Type:请求的资源MIME类型
Initiator: 发起请求的对象或进程,他可能有以下值:

  • Parser(解析器):Chrome的 HTML 解析器发起了请求(鼠标悬停显示JS脚本)
  • Redirect(重定向):HTTP重定向启动了请求
  • Script(脚本):脚本启动了请求
  • Other(其他):一些其他进程或动作发起请求,例如用户点击链接跳转到页面或在地址栏中输入网址。
    Size:服务器返回的相应大小(包括头部和包体),可显示解压后大小;注意:如果网络正常,但是网页加载资源很慢,可以看下是否某些资源的size很大,导致页面加载慢。
    Time:总持续时间,从请求开始到接受响应的最后一个字节
    Waterfall:各请求相关活动的直观分析图

canal的dockerfile构建

FROM canal/canal-server:v1.1.5
RUN mkdir /home/admin/canal-server/conf/estate/
RUN mv /home/admin/canal-server/conf/example /tmp/
ADD instance.properties /home/admin/canal-server/conf/estate/
EXPOSE 11110 11111 11112 9100
WORKDIR /home/admin
ENTRYPOINT [ "/alidata/bin/main.sh" ]
CMD [ "/home/admin/app.sh" ]

出自https://github.com/alibaba/canal/blob/master/docker/Dockerfile

Python3 https证书有效期

#!/usr/bin/env python3
# -*-coding:utf8-*-

import re
import time
import subprocess
from datetime import datetime
from io import StringIO

def main(domain):
f = StringIO()
comm = f"curl -Ivs https://{domain} --connect-timeout 10"

result = subprocess.getstatusoutput(comm)
f.write(result[1])

m = re.search('start date: (.*?)\n.*?expire date: (.*?)\n.*?common name: (.*?)\n.*?issuer: CN=(.*?)\n', f.getvalue(), re.S)
start_date = m.group(1)
expire_date = m.group(2)
common_name = m.group(3)
issuer = m.group(4)

# time 字符串转时间数组
start_date = time.strptime(start_date, "%b %d %H:%M:%S %Y GMT")
start_date_st = time.strftime("%Y-%m-%d %H:%M:%S", start_date)
# datetime 字符串转时间数组
expire_date = datetime.strptime(expire_date, "%b %d %H:%M:%S %Y GMT")
expire_date_st = datetime.strftime(expire_date,"%Y-%m-%d %H:%M:%S")

# 剩余天数
remaining = (expire_date-datetime.now()).days

print('域名:', domain)
print('通用名:', common_name)
print('开始时间:', start_date_st)
print('到期时间:', expire_date_st)
print(f'剩余时间: {remaining}天')
print('颁发机构:', issuer)
print(remaining)
print('*'*30)

time.sleep(0.5)

if __name__ == "__main__":

domains = ['www.baidu.com']

for domain in domains:
main(domain)

调用jquery时,注意路径的引用

<!DOCTYPE html><html><head>
<meta charset="UTF-8">
<script src="/jquery.js"></script> //注意有/,加载效果失败
<script type="text/javascript">
$(document).ready(function(){
$(".flip").click(function(){
$(".panel").slideToggle("slow");
});
});
</script>
<style type="text/css">
div.panel,p.flip
{
margin:0px;
padding:5px;
text-align:center;
background:#e5eecc;
border:solid 1px #c3c3c3;
}
div.panel
{
height:120px;
display:none;
}
</style>
</head>
<body>
<div class="panel">
<p>学习前端课程</p>
<p>深入浅出前端系列</p>
</div>
<p class="flip">请点击这里</p>
</body>
</html>
<!DOCTYPE html><html><head>
<meta charset="UTF-8">
<script src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".flip").click(function(){
$(".panel").slideToggle("slow");
});
});
</script>
<style type="text/css">
div.panel,p.flip
{
margin:0px;
padding:5px;
text-align:center;
background:#e5eecc;
border:solid 1px #c3c3c3;
}
div.panel
{
height:120px;
display:none;
}
</style>
</head>
<body>
<div class="panel">
<p>学习前端课程</p>
<p>深入浅出前端系列</p>
</div>
<p class="flip">请点击这里</p>
</body>
</html>
点击后上下切换

前端测试

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>New tec</title>
</head>
<body>
<div id="header">
<h1>四川省</h1>
</div>
<div id="nav">
成都<br>
德阳<br>
绵阳<br>
遂宁<br>
</div>
<div id="section">
<h1>CD</h1>
<p>
成都历史悠久,有“天府之国”、“蜀中江南”、“蜀中苏杭”的美称。据史书记载,大约在公元前5世纪中叶的古蜀国开明王朝九世时将都城从广都樊乡(双流)迁往成都,构筑城池。 关于成都一名的来历,据《太平环宇记》记载,是借用西周建都的历史经过,取周王迁岐“一年而所居成聚,二年成邑,三年成都”而得名成都。蜀语“成都”二字的读音就是蜀都。 “‘成’者‘毕也’‘终也’”,成都的含义“就是蜀国‘终了的都邑’,或者说‘最后的都邑’。五代十国时,后蜀皇帝孟昶偏爱芙蓉花,命百姓在城墙上种植芙蓉树,花开时节, 成都“四十里为锦绣”,故成都又被称为芙蓉城,简称“蓉城”。2001年2月8日出土的金沙遗址,已经将成都建城历史从公元前311年提前到了公元前611年。
</p>
<p>

</div>
<div id="footer">
Copyright www.tcc.pub
</div>
</body>
<style>
#header {
background-color:darkblue;
color:white;
text-align:center;
padding:10px;
}
#nav {
line-height:30px;
background-color:#eeeeee;
height:400px;
width:100px;
float:left;
padding:20px;
}
#section {
width:350px;
float:left;
padding:10px;
}
#footer {
background-color:black;
color:white;
clear:both;
text-align:center;
padding:5px;
}
</style>
</html>