
开发工具【免费下载链接】jcCLI tool and python library that converts the output of popular command-line tools, file-types, and common strings to JSON, YAML, or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.项目地址https://gitcode.com/gh_mirrors/jc/jc点击查看免费下载hciconfig是 Linux 下 bluez 工具集提供的蓝牙设备配置命令其输出为多块对齐的纯文本包含每个蓝牙控制器hciX的地址、MTU、收发统计、特性与版本等信息难以直接被脚本消费。jc 项目的hciconfig解析器版本 1.4兼容 Linux将该命令输出整体转换为 JSON / YAML / Python 字典可直接接入jq、jmespath或自动化巡检脚本。阅读本文后你将掌握该解析器的 CLI 与模块调用方式、完整的输出字段语义、raw/processed 两种模式差异以及其底层逐行解析与类型转换的实现原理。一、解析器定位把 hciconfig 变成机器可读数据jcJSON Convert是一个将常见命令行工具输出转换为 JSON、YAML 或字典的 CLI 工具与 Python 库。hciconfig解析器对应源码为 jc/parsers/hciconfig.py其元信息声明于info类中class info(): version 1.4 description hciconfig command parser author Kelly Brazil author_email kellyjonbrazilgmail.com compatible [linux] magic_commands [hciconfig] tags [command]两点值得注意兼容平台compatible [linux]解析器仅在 Linux 平台生效在非 Linux 系统上调用时jc 会通过jc.utils.compatibility()向STDERR输出兼容性警告除非设置quietTrue。magic 命令magic_commands [hciconfig]表明该解析器支持 magic 自动运行模式见下文。二、三种调用方式1. 管道模式显式指定解析器这是最常见的用法将hciconfig输出直接喂给 jc$ hciconfig | jc --hciconfig2. Magic 模式自动执行命令直接运行jc hciconfigjc 会替你执行该命令并自动匹配解析器$ jc hciconfig其底层机制在 jc/cli.pyjc 遍历所有解析器的magic_commands元数据构建magic_dict命令名 → 解析器参数名映射再对用户输入的命令做单/双词匹配命中hciconfig后调用run_user_command()执行命令并解析。这意味着无需手动管道一条命令即可完成执行 转换。3. Python 模块调用在脚本中引入 jc 库直接解析字符串import jc result jc.parse(hciconfig, hciconfig_command_output)result是字典列表List of Dictionaries每个字典对应一个蓝牙控制器。三、输出 Schema 全解解析器返回一个数组每个元素对应一台蓝牙设备hci0、hci1……字段语义如下字段类型说明devicestring蓝牙设备接口名如hci0typestring设备类型如Primarybusstring连接总线如USBbd_addressstring蓝牙设备地址BD Address形如00:1A:7D:DA:71:13acl_mtuintegerACL 链路 MTU 大小acl_mtu_packetsintegerACL 链路可缓冲数据包数sco_mtuintegerSCO 链路 MTU 大小sco_mtu_packetsintegerSCO 链路可缓冲数据包数statestring[]控制器状态可能含UP、RUNNING、DOWN等rx_bytesinteger累计接收字节数rx_aclinteger接收的 ACL 数据包数rx_scointeger接收的 SCO 数据包数rx_eventsinteger接收的事件数rx_errorsinteger接收错误数tx_bytesinteger累计发送字节数tx_aclinteger发送的 ACL 数据包数tx_scointeger发送的 SCO 数据包数tx_commandsinteger发送的命令数tx_errorsinteger发送错误数featuresstring[]控制器支持的特性位图8 个十六进制字节packet_typestring[]支持的包类型如DM1、DH5、HV3link_policystring[]链路策略如RSWITCH、HOLD、SNIFF、PARKlink_modestring[]链路模式如SLAVE、ACCEPTnamestring设备友好名称仅-a输出且设备开启时出现classstring设备类别码十六进制如0x000000service_classesstring[]服务类别列表当取值仅为Unspecified时processed 模式下转为nulldevice_classstring设备类别描述如Miscellaneoushci_versionstringHCI 规范版本如4.0 (0x6)hci_revisionstringHCI 修订号如0x22bblmp_versionstringLMP 版本如4.0 (0x6)lmp_subversionstringLMP 子版本号如0x22bbmanufacturerstring制造商名称及 ID如Cambridge Silicon Radio (10)注意并非所有字段都会出现。普通hciconfig不加-a的每块输出只包含前 14 个字段设备、地址、MTU、状态、RX/TX 统计-a显示所有信息才会额外补充 features、packet_type、link_policy、link_mode、name、class、service_classes 等详细字段。这一点从仓库 fixture 可以印证centos-7.7/hciconfig.json 只有基础字段而 centos-7.7/hciconfig-a.json 则包含完整字段集。四、实战示例processed 与 raw 模式1. 标准输出processed-p美化缩进以 Ubuntu 20.04 上同时存在两块 USB 蓝牙适配器的场景为例$ hciconfig -a | jc --hciconfig -p输出节选自 ubuntu-20.04/hciconfig-a.json两块设备对应一个列表的两个元素[ { device: hci0, type: Primary, bus: USB, bd_address: 00:1A:7D:DA:71:13, acl_mtu: 310, acl_mtu_packets: 10, sco_mtu: 64, sco_mtu_packets: 8, state: [ UP, RUNNING ], rx_bytes: 13905869, rx_acl: 0, rx_sco: 0, rx_events: 393300, rx_errors: 0, tx_bytes: 62629, tx_acl: 0, tx_sco: 0, tx_commands: 3893, tx_errors: 0, features: [ 0xff, 0xff, 0x8f, 0xfe, 0xdb, 0xff, 0x5b, 0x87 ], packet_type: [ DM1, DM3, DM5, DH1, DH3, DH5, HV1, HV2, HV3 ], link_policy: [ RSWITCH, HOLD, SNIFF, PARK ], link_mode: [ SLAVE, ACCEPT ], name: CSR8510 A10, class: 0x000000, service_classes: null, device_class: Miscellaneous, hci_version: 4.0 (0x6), hci_revision: 0x22bb, lmp_version: 4.0 (0x6), lmp_subversion: 0x22bb, manufacturer: Cambridge Silicon Radio (10) }, { device: hci1, type: Primary, bus: USB, bd_address: 00:1A:7D:DA:71:13, acl_mtu: 310, acl_mtu_packets: 10, sco_mtu: 64, sco_mtu_packets: 8, state: [ DOWN ], tx_errors: 2 } ]其中service_classes为null因为原始文本只有Service Classes: Unspecifiedstate被解析为字符串数组而非单个字符串这些都属于 processed 模式下的规范化行为。2. 原始输出raw-r$ hciconfig -a | jc --hciconfig -p -rraw 模式下所有数值字段保持字符串类型如acl_mtu: 310service_classes也不再折叠为null而是保留原始[Unspecified]。上述例子的service_classes在 raw 输出中即为service_classes: [ Unspecified ]3. 与 jq 联动做设备巡检转换后的 JSON 可直接交给jq过滤。例如筛选出所有处于UP状态设备的地址与收发统计$ hciconfig -a | jc --hciconfig | jq .[] | select(.state | index(UP)) | {device, bd_address, rx_bytes, tx_bytes}五、源码级实现剖析逐行状态机解析解析器核心是 jc/parsers/hciconfig.py 中的parse()函数采用逐行扫描 行内容匹配的状态机方式不依赖正则表达式而是按行前缀精确识别。整体流程为jc.utils.compatibility()校验平台兼容性jc.utils.input_type_check()校验输入必须是字符串jc.utils.has_data()判断输入是否为空——空输入直接返回[]。对data.splitlines()过滤空行后逐行处理。行首是否缩进决定了它是新设备块的标题行还是设备属性行。关键分支逻辑如下对应 parse 函数输入行特征提取字段行首无空白如hci0: Type: Primary Bus: USB结束上一设备对象开启新对象去掉冒号后按空格切分取device、type、busBD Address: ... ACL MTU: X:Y SCO MTU: A:Bbd_address、acl_mtu、acl_mtu_packets、sco_mtu、sco_mtu_packetsMTU 以:再切分每设备块的第 3 行line_count 3state直接按空白切分成数组RX bytes:... acl:... sco:... events:... errors:...rx_bytes、rx_acl、rx_sco、rx_events、rx_errorsTX bytes:... acl:... sco:... commands:... errors:...tx_bytes、tx_acl、tx_sco、tx_commands、tx_errorsFeatures: ...features去掉首词后的全部标记Packet type: ...packet_type去掉前两个词Link policy: ...link_policyLink mode: ...link_modeName: ...namemaxsplit1切分后剥掉首尾单引号Class: ...classService Classes: ...service_classes去掉前两个词后的列表Device Class: Miscellaneous,device_class去掉末尾逗号HCI Version: 4.0 (0x6) Revision: 0x22bbhci_version合并版本号与括号值、hci_revisionLMP Version: 4.0 (0x6) Subversion: 0x22bblmp_version、lmp_subversionManufacturer: ...manufacturer两个实现细节值得说明state 的定位方式state位于每块的第 3 行设备标题行之后、RX 统计之前源码用line_count计数并在设备块切换时重置为 1 来定位而不是依赖关键字匹配UP RUNNING、DOWN等并无统一前缀。块边界判定if not line[0].isspace()判定非缩进行即新设备标题行此时若已有未完成的device_object就先行追加到raw_output因此解析结果天然是一个按设备分组的列表。六、数据处理类型转换与 service_classes 折叠raw 解析完成后若rawFalse会调用_process()做最终规范化源码位置int_list { acl_mtu, acl_mtu_packets, sco_mtu, sco_mtu_packets, rx_bytes, rx_acl, rx_sco, rx_events, rx_errors, tx_bytes, tx_acl, tx_sco, tx_commands, tx_errors }整数转换上表 14 个字段统一经jc.utils.convert_to_int()从字符串转为int。该工具函数会剥离字符串中的非数字字符转换失败时返回None参考 jc/utils.py 的convert_to_int。service_classes 折叠若service_classes列表长度恰为 1 且内容为Unspecified则置为None。这正是文档 schema 中注释# Unspecified is null的实现依据——原始文本Service Classes: Unspecified表示设备未声明明确服务类别折叠为null更符合语义也避免下游脚本把无意义字符串当数据。七、测试与 fixture 验证仓库在 tests/test_hciconfig.py 中为该解析器提供了完整的单元测试覆盖多平台输出形态空数据parse(, quietTrue)应返回[]。CentOS 7.7普通hciconfig与hciconfig -a输出对应 fixture tests/fixtures/centos-7.7/hciconfig-a.out单设备、DOWN状态、仅基础字段期望 JSON 见 tests/fixtures/centos-7.7/hciconfig-a.json。Ubuntu 20.04同样两组用例对应 fixture tests/fixtures/ubuntu-20.04/hciconfig-a.out双设备UP RUNNING/DOWN并存含 Name、Class、Manufacturer 等全部详细字段与 tests/fixtures/ubuntu-20.04/hciconfig-a.json。对比两组 fixture 可以清晰看到不同发行版/内核下hciconfig输出行的缩进宽度4 空格 vs 8 空格并不影响解析因为解析器只依赖行首是否有空白和行前缀关键字而非精确缩进列数。这也是该解析器在 CentOS 与 Ubuntu 上都能稳定工作的原因。八、适用前提与限制平台限制解析器声明兼容 LinuxmacOS 的蓝牙工具输出格式不同该平台请使用system_profiler相关解析器不要直接套用。命令形态普通hciconfig输出只有基础统计字段需要完整的设备信息名称、类别、特性、版本、制造商时请使用hciconfig -a。字段缺失处于DOWN状态的设备其输出不含name、class、service_classes、hci_version等字段解析结果中这些键不会出现脚本消费时应使用.get()或先做存在性判断。数据口径rx_*/tx_*为设备累计统计值与hciconfig -a输出时的瞬时快照一致适合做周期性采集与差分监控。赞分享开发工具【免费下载链接】jcCLI tool and python library that converts the output of popular command-line tools, file-types, and common strings to JSON, YAML, or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.项目地址https://gitcode.com/gh_mirrors/jc/jc点击查看免费下载相关推荐jc 解析器实战将 id 命令输出转换为结构化 JSON 的完整指南jc 解析器实战将 id 命令输出转换为结构化 JSON 的完整指南 id 命令是 Linux/macOS 系统上查看当前用户身份信息UID、GID、所属组开发工具jc net_localgroup 解析器将 Windows net localgroup 输出转为结构化 JSON 的完整指南jc net_localgroup 解析器将 Windows net localgroup 输出转为结构化 JSON 的完整指南 Windows 本地组lo开发工具jc 的 file 命令解析器将 file * 输出转换为结构化 JSONjc 的 file 命令解析器将 file 输出转换为结构化 JSON 导读 file 命令是 Linux / macOS 系统上最常用的文件类型探测工具但开发工具上一篇如何用InstagramOSINT快速获取目标账号16项核心信息新手入门教程下一篇ElasticHQ 终极指南从零开始掌握 Elasticsearch 集群监控与管理的完整教程 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考