SocketCAN 命名空间 VCAN VXCAN CANGW 举例

news2024/11/29 10:46:54

文章目录

    • NAMESPACE
    • SocketCAN
    • 最新 can-utils 安装
    • VCAN 举例
    • VXCAN 举例
    • CANGW 举例
    • 参考

NAMESPACE

namespaces, 命名空间, 将全局系统资源包装在抽象中, 使命名空间中的进程看起来拥有自己全局资源的独立实例. 命名空间的一个用途是实现容器.

Linux 命名空间类型及隔离物(Isolates):

  • Cgroup, Cgroup根目录
  • IPC, System V IPC, POSIX消息队列
  • Network, 网络设备, 堆叠, 端口等
  • Mount, 挂载点
  • PID, 进程ID
  • Time, 启动和单调时钟
  • User, 用户和组ID
  • UTS, 主机名和NIS域名

随着不断发展, 命名空间的类型也可能继续增删. SocketCAN 属于网络, 所以本篇主要是用到 Network 网络命名空间.

SocketCAN

SocketCAN, 是Linux的CAN协议实现, 使用 Berkeley socket API, Linux网络堆栈, 把 CAN 设备驱动实现为网络接口. CAN 的 socket API 设计与 TCP/IP 协议尽可能相似, 熟悉网络编程就能轻松的使用 SocketCAN.

SocketCAN 网络层协议和帧处理 的参考示意图:

在这里插入图片描述

其中:

  • CAN_RAW, 读取和写入 CAN 帧, 经过了接收过滤器(receive filters), Linux ns时间戳, 单个CAN口允许多个应用独立运行, 本地回显可实现网络透传, CAN_RAW 经常配合 bind 使用
  • CAN_BCW, Broadcast Manager, 循环消息的计时器和过滤器支持, 收发路径功能, 逐位过滤 CAN 帧 payload, 检测超时, 多路 CAN 消息的即时数据更新, CAN_BCW 需要配合 connect 使用, 当使用 recvfrom() 而不是 read() 检索BCM套接字消息时, can_ifindex 提供了原始 CAN 接口. 通过 CAN_BCM 可以方便的把 CAN 对接到其它接口如 ETH, UART 等
  • ISO-TP, ISO 15765-2 定义的 CAN 传输协议, 已经合并进 Linux 主线内核 5.10 及以后的版本. ISO-TP 将较长消息分割成多帧, 添加元数据(metadata), 允许接收方解释各个帧并重新组合成完整消息包. 先前版本 payload 限制最大4095字节, ISO 15765-2:2016 之后的版本扩大为 2^32-1 = 4294967295 字节(4GB -1)
  • CAN_GW, 基于Linux内核的 CAN 帧路由, 可使用 PF_CAN 接收滤波器, NET_RX 软中断, 基于 PF_NETLINK 的类似 iptables 的配置接口, 可动态修改CAN帧, 用 AND/OR/XOR/SET 操作改变 CAN 标识符, DLC, payload 数据等, 修改后可计算 XOR 和 CRC8, 支持不同的 CRC8 配置(1U8, 16U8, SFFID_XOR)

这里顺便列下 ISO 15765 (headlined Road vehicles — Diagnostic communication over Controller Area Network (DoCAN)):

  • ISO 15765-1, 通用信息和用例定义
  • ISO 15765-2, 传输协议和网络层服务 (ISO-TP)
  • ISO 15765-3, 实现统一诊断服务 (UDS on CAN), 已过时, 替换为 ISO14229-3 (CAN, ETH, UART => DoCAN, DoIP等)
  • ISO 15765-4, emissions 等相关系统的需求

以 Orin 为例, 一个典型的2路 SocketCAN 的启动脚本:

#!/bin/sh

# 寄存器配置
sudo busybox devmem 0x0c303000 32 0x0000C400
sudo busybox devmem 0x0c303008 32 0x0000C458
sudo busybox devmem 0x0c303010 32 0x0000C400
sudo busybox devmem 0x0c303018 32 0x0000C458

# Module 加载
sudo modprobe can
sudo modprobe can_raw
sudo modprobe mttcan

# TDC 配置, 以支持 2M 以上 CANFD
sudo sh -c 'echo 0x600 > /sys/devices/platform/c310000.mttcan/net/can0/tdc_offset'
sudo sh -c 'echo 0x600 > /sys/devices/platform/c320000.mttcan/net/can1/tdc_offset'

# CAN0 配置
sudo ip link set down can0
sudo ip link set can0 type can bitrate 500000 sample-point 0.8 dbitrate 5000000 dsample-point 0.8 berr-reporting on fd on restart-ms 100
sudo ip link set up can0 mtu 72
sudo ifconfig can0 txqueuelen 1000
# ip -s -d link show can0

# CAN1 配置
sudo ip link set down can1
sudo ip link set can1 type can bitrate 500000 sample-point 0.8 dbitrate 5000000 dsample-point 0.8 berr-reporting on fd on restart-ms 100
sudo ip link set up can1 mtu 72
sudo ifconfig can1 txqueuelen 1000
# ip -s -d link show can1

一个典型的 SocketCAN 的应用初始化例子如下:

{
	int s;
    struct sockaddr_can addr;
    struct ifreq ifr;

    if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
        perror("Error while opening socket");
        return -1;
    }

    strcpy(ifr.ifr_name, "can0" );
    ioctl(s, SIOCGIFINDEX, &ifr);

    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    
    // CANFD 支持
    int enable_canfd = 1;
    if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
		&enable_canfd, sizeof(enable_canfd))) {
		printf("error when enabling CAN FD support\n");
		return 1;
	}
	
	// 滤波器, 略

    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("Error in socket bind");
        return -2;
    }
}

初始化后可以使用正常的 read 和 write, 多个 socketcan 接口可以类似网络那样使用 epoll 等进行管理. c++ 的 asio 同样支持.

最新 can-utils 安装

can-utils 是 Linux CAN/SocketCAN 的用户空间应用程序. 如常见的 cansend, candump 等

之前的 cangw 对 canfd 的支持并不好, 在新版 can-utils 提供了支持, 可直接从源码编译安装:

git clone https://github.com/linux-can/can-utils.git
cd can-utils
mkdir build && cd build && make -j12 && sudo make install

VCAN 举例

Linux 虚拟网络 的功能异常丰富, 为容器等打下了坚实的技术基础.

VCAN, Virtual CAN, 类似于虚拟的网络 loopback 设备, 在本机测试CAN协议实现时, 可以使用 VCAN.

在这里插入图片描述

实现上图的一个 vcan0 的脚本

#!/bin/bash
# if -c parameter is given, then clean up
if [ "$1" = "-c" ]; then
    sudo ip link set down vcan0
    sudo ip link delete vcan0
    exit 0
fi
sudo modprobe can
sudo modprobe can-raw
sudo modprobe vcan
# if vcan0 is already created, delete it
if [ -e /sys/class/net/vcan0 ]; then
    sudo ip link set down vcan0
    sudo ip link delete vcan0
fi
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0

是的, vcan 无需设置通信速率等, 内核跑多快, 速率就有多快, 自带 loopback, 多个 app 可以通过单个 vcan 通信. can 和 canfd 也都支持的不错, 命名也不必 vcanx, 取名 dog, vcanpig 也可以

# 可以多个窗口开多个candump
$ candump -td -x vcan0
 (000.000000)  vcan0  TX - -  123   [2]  11 22
 (025.888347)  vcan0  TX B E  12345678  [12]  11 22 33 44 55 66 77 88 99 00 00 00
 
$ cansend vcan0 123#11.22
$ cansend vcan0 12345678##3.11.22.33.44.55.66.77.88.99

VXCAN 举例

VXCAN, Virtual CAN Tunnel, 与 veth 类似, 实现了 CAN 流量隧道, 创建 VXCAN 时, 两个 VXCAN 设备会成对创建, 可用于跨命名空间通信, 不提供本地回显 loopback. 见于 Linux 4.12 内核以后

在这里插入图片描述

实现上图的一个 vxcan 的脚本

#!/bin/bash

# if -c parameter is given, then clean up
if [ "$1" = "-c" ]; then
    sudo ip link set down vxcan0
    sudo ip link delete vxcan0
    exit 0
fi

sudo modprobe can
sudo modprobe can_raw
sudo modprobe vxcan

sudo ip link add vxcan0 type vxcan peer name vxcan1
sudo ip link set vxcan0 up
sudo ip link set vxcan1 up

说明:

  • 删除一对中的任意一个, 另一个也会消失
  • 默认支持 can 和 canfd

运行后, 可以看到多出一对 vxcan 设备

$ ip link
22: vxcan1@vxcan0: <NOARP,UP,LOWER_UP> mtu 72 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/can 
23: vxcan0@vxcan1: <NOARP,UP,LOWER_UP> mtu 72 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/can 
    
$ candump -td -x any
 (000.000000)  vxcan1  TX B E  123  [12]  11 22 33 44 55 66 77 88 99 00 00 00
 (000.000020)  vxcan0  TX B E  123  [12]  11 22 33 44 55 66 77 88 99 00 00 00
 (008.254112)  vxcan0  TX B E  12345678  [12]  11 22 33 44 55 66 77 88 99 00 00 00
 (000.000021)  vxcan1  TX B E  12345678  [12]  11 22 33 44 55 66 77 88 99 00 00 00
 
$ cansend vxcan0 123##3.11.22.33.44.55.66.77.88.99
$ cansend vxcan1 12345678##3.11.22.33.44.55.66.77.88.99

下面是一个跨命名空间通信的例子

  • 除了 host, 还有 netns1, netns2 两个网络命名空间
  • vxcan0-vxcan1 连接了 netns1, netns2 两个网络命名空间
  • vxcan2-vxcan3 连接了 netns1 和 host
  • app1 既能和 app2/app3 通信, 也能和 app4 通信

在这里插入图片描述

实现上图的脚本

#!/bin/bash

# if -c parameter is given, then clean up
if [ "$1" = "-c" ]; then
    sudo ip netns del ns1
    sudo ip netns del ns2
    # sudo ip link set down vxcan2
    # sudo ip link delete vxcan2
    exit 0
fi

sudo modprobe can
sudo modprobe can_raw
sudo modprobe vxcan

# ns1 - ns2
sudo ip netns add ns1
sudo ip netns add ns2
sudo ip link add vxcan0 netns ns1 type vxcan peer name vxcan1 netns ns2
sudo ip netns exec ns1 ip link set vxcan0 up
sudo ip netns exec ns2 ip link set vxcan1 up

# ns1 - host
sudo ip link add vxcan2 netns ns1 type vxcan peer name vxcan3
sudo ip netns exec ns1 ip link set vxcan2 up
sudo ip link set vxcan3 up

运行后, 可以在各自的命名空间查看

$ ip link
24: vxcan3@if5: <NOARP,UP,LOWER_UP> mtu 72 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/can  link-netns ns1
    
    
$ sudo ip netns exec ns1 ip link
4: vxcan0@if4: <NOARP,UP,LOWER_UP> mtu 72 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/can  link-netns ns2
5: vxcan2@if24: <NOARP,UP,LOWER_UP> mtu 72 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/can  link-netnsid 1
    
$ sudo ip netns exec ns2 ip link
4: vxcan1@if4: <NOARP,UP,LOWER_UP> mtu 72 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/can  link-netns ns1

收发测试

# ns1,vxcan0 - ns2,vxcan1
$ sudo ip netns exec ns1 candump -td -x any
$ sudo ip netns exec ns2 candump -td -x any
$ sudo ip netns exec ns1 cansend vxcan0 123##3.11.22
$ sudo ip netns exec ns2 cansend vxcan1 123##3.11.23

# ns1,vxcan2 - host,vxccan3
$ sudo ip netns exec ns1 candump -td -x any
$ candump -td -x any
$ sudo ip netns exec ns1 cansend vxcan2 123##3.11.22
$ cansend vxcan3 123##3.11.23

如果嫌前缀 sudo ip netns exec ns1 过长的话, 可以先进入ns1: sudo ip netns exec ns1 bash. 其它命令举例

$ ip netns list
ns2
ns1 (id: 0)

$ sudo ip netns exec ns2 lsns
        NS TYPE   NPROCS    PID USER            COMMAND
4026533123 mnt        10  85584 root            /init
$ sudo nsenter -t 85584 -n bash
# exit 或 Ctrl+D 退出这个bash

CANGW 举例

安装 can-utils 后就可以使用 cangw 命令了

先来查看下 help, 可以看出, 新的 can-utils 中的 cangw 已经支持了 canfd

$ cangw help
cangw - manage PF_CAN netlink gateway.

Usage: cangw [options]

Commands:
          -A  (add a new rule)
          -D  (delete a rule)
          -F  (flush / delete all rules)
          -L  (list all rules)
Mandatory:
          -s <src_dev>  (source netdevice)
          -d <dst_dev>  (destination netdevice)
Options:
          -X  (this is a CAN FD rule)
          -t  (preserve src_dev rx timestamp)
          -e  (echo sent frames - recommended on vcanx)
          -i  (allow to route to incoming interface)
          -u <uid>  (user defined modification identifier)
          -l <hops>  (limit the number of frame hops / routings)
          -f <filter>  (set CAN filter)
          -m <mod>  (set Classical CAN frame modifications)
          -M <MOD>  (set CAN FD frame modifications)
          -x <from_idx>:<to_idx>:<result_idx>:<init_xor_val>  (XOR checksum)
          -c <from>:<to>:<result>:<init_val>:<xor_val>:<crctab[256]>  (CRC8 cs)
          -p <profile>:[<profile_data>]  (CRC8 checksum profile & parameters)

Values are given and expected in hexadecimal values. Leading 0s can be omitted.
...

cangw 可以把 真实的can, vcan, vxcan 连起来, 如

在这里插入图片描述

或者

在这里插入图片描述

此图中 app0 可以和 app2, app3, app4, app5 进行通信, 脚本如下

#!/bin/bash

# if -c parameter is given, then clean up
if [ "$1" = "-c" ]; then
    sudo cangw -F -s vcan0 -d vxcan0
    sudo cangw -F -s vxcan0 -d vcan0
    cangw -L
    sudo ip link set down vxcan0
    sudo ip link delete vxcan0
    sudo ip link set down vcan0
    sudo ip link delete vcan0
    exit 0
fi

sudo modprobe can
sudo modprobe can_raw
sudo modprobe can-gw
sudo modprobe vcan
sudo modprobe vxcan

# vxcan
sudo ip link add vxcan0 type vxcan peer name vxcan1
sudo ip link set vxcan0 up
sudo ip link set vxcan1 up

# vcan
sudo ip link add vcan0 type vcan
sudo ip link set vcan0 up

# cangw
sudo cangw -A -s vcan0 -d vxcan1 -e
sudo cangw -A -s vxcan0 -d vcan0 -e
sudo cangw -A -X -s vcan0 -d vxcan0 -e
sudo cangw -A -X -s vxcan0 -d vcan0 -e

说明:

  • -A, add, 添加规则
  • -s, source, 源
  • -d, destination
  • -e, echo sent frames - recommended on vcanx, 回显
  • -X, CAN FD支持, 这里标准 CAN 和 CAN FD 分开写了, 不知道未来会不会合并

查看 cangw 规则列表

$ cangw -L
cangw -A -s vxcan0 -d vcan0 -e # 0 handled 0 dropped 0 deleted
cangw -A -s vcan0 -d vxcan0 -e # 0 handled 0 dropped 0 deleted
cangw -A -s vxcan0 -d vcan0 -e # 0 handled 0 dropped 0 deleted
cangw -A -s vcan0 -d vxcan1 -e # 0 handled 0 dropped 0 deleted

测试

$ candump -td -x any
 (000.000000)  vxcan1  TX - -  123   [1]  11
 (000.000036)  vxcan0  TX - -  123   [1]  11
 (000.000003)   vcan0  RX - -  123   [1]  11
 (005.983670)  vxcan1  TX B E  123  [02]  11 22
 (000.000039)  vxcan0  TX B E  123  [02]  11 22
 (000.000003)   vcan0  RX B E  123  [02]  11 22
 (011.298185)   vcan0  TX B E  123  [03]  11 22 33
 (000.000041)  vxcan1  RX B E  123  [03]  11 22 33
 (000.000000)  vxcan0  RX B E  123  [03]  11 22 33
 (013.869664)   vcan0  TX - -  123   [4]  11 22 33 44
 (000.000041)  vxcan0  RX - -  123   [4]  11 22 33 44
 (000.000001)  vxcan1  RX - -  123   [4]  11 22 33 44
 
$ cansend vxcan0 123#11
$ cansend vxcan0 123##3.11.22
$ cansend vcan0 123##3.11.22.33
$ cansend vcan0 123#11.22.33.44

参考

  • linux-can/can-utils: Linux-CAN / SocketCAN user space applications (github.com)
  • SocketCAN mit Docker unter Linux, PPT
  • SocketCAN mit Docker unter Linux, Video
  • SocketCAN + Docker = The solution
  • Design & separation of CAN applications
  • SocketCAN - Controller Area Network
  • Introduction to Linux interfaces for virtual networking
  • WSL 和 Jetson 的内核 vxcan 支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

译文 | Kubernetes 1.26:PodDisruptionBudget 守护不健康 Pod 时所用的驱逐策略

对于 Kubernetes 集群而言&#xff0c;想要确保日常干扰不影响应用的可用性&#xff0c;不是一个简单的任务。上月发布的 Kubernetes v1.26 增加了一个新的特性&#xff1a;允许针对 PodDisruptionBudget (PDB) 指定不健康 Pod 驱逐策略&#xff0c;这有助于在节点执行管理操作…

电商云仓是如何包装发货的?

包装不时是为了维护产品&#xff0c;而它从工厂地板移动到大型仓库&#xff0c;并最终经过批发或批发店抵达消费者。但是&#xff0c;自21世纪初以来&#xff0c;消费者希望与那些不时吸收着某种情感的品牌联络在一同&#xff0c;同时央求他们在心理上对品牌中止投资&#xff0…

【Java AWT 图形界面编程】Canvas 组件中使用 Graphics 绘图 ④ ( AWT 绘图窗口闪烁问题 )

文章目录一、AWT 绘图窗口闪烁问题二、完整代码示例一、AWT 绘图窗口闪烁问题 使用 Graphics 第一次绘图 完成后 , 如果在循环中 持续调用 Canvas#repaint() 函数刷新界面 , 代码如下 : import java.awt.*;public class HelloAWT {public static void main(String[] args) thr…

MySQL进阶——存储引擎

MySQL有9种存储引擎&#xff0c;不同的引擎&#xff0c;适合不同的场景&#xff0c;我们最常用的&#xff0c;可能就是InnoDB&#xff0c;应该是从5.5开始&#xff0c;就成为了MySQL的默认存储引擎。 show engines可以查询MySQL支持的这几种存储引擎&#xff0c;从表头能看出来…

SVN工程转Git工程Github托管

SVN工程转Git工程&Github托管1. 介绍2. autoAudioTest之SVN转Github步骤Step 1 工作环境(ubuntu)Step 2 安装升级必要软件Step 3 转换脚本Step 4 检查软件运行环境Step 5 生成authors.txtStep 6 SVN转换Git格式Step 7 Github新建空工程Step 8 Git提交已有工程Step 9 Git提交…

Dubbo快速入门看这一篇文章就够了

网站用户少,流量小,抗压力差(eg: ssm)网站用户量进一步增长,流量增多,服务器不能平滑扩容(eg: 多个ssm)网站用户和流量随时间稳步升高,需要随时进行服务器扩容(eg: rpc/http) 第2节 分布式框架解决的问题 1 2 3 4 5 6随着互联网架构的越来越复杂,由原来的单一架构 ...到... 流动…

M320、M601、HD1(RTU)功能对比

M320、M601、HD1_RTU硬件 / 软件功能对比一、硬件1.HD1-RTU2.Haas506-M3203.Haas506-M6014.对比区别二、软件1.对比区别一、硬件 1.HD1-RTU 详情参考HaaS506-HD1 (RTU) - 硬件介绍 2.Haas506-M320 详情参考HaaS506-M320 - 开发板介绍 3.Haas506-M601 详情参考HaaS506…

(二十二)简单算法和Lambda表达式

目录 前言: 1.选择排序 2.二分查找 3.Lambda表达式 前言: 算法是一个程序和软件的灵魂&#xff0c;要成为一名优秀的程序员&#xff0c;只有对基础算法全面掌握&#xff0c;才能在设计程序和编写代码的过程中显得得心应手。常用的基础算法有快速排序算法、堆排序算法、归并排…

每日一问-ChapGPT-20230115-关于断舍离

文章目录每日一问-ChapGPT系列起因每日一问-ChapGPT-20230115-关于断舍离人类脑是适合专心做一件事&#xff0c;还是适合并行做多件事做事情的优先顺序怎样安排chapGPT你是怎么学到这么多知识的chapGPT你拥有智慧吗chapGPT你是实时更新自己的模型吗chapGPT你有情感吗chapGPT你有…

C++程序卡死、UI界面卡顿问题的原因分析与总结

目录 1、概述 2、软件卡死问题 2.1、死循环 2.2、死锁 3、客户端软件的UI界面卡顿问题 3.1、UI线程在频繁地写日志到文件中&#xff0c;导致UI线程时不时的卡顿 3.2、从网上拷贝的代码中调用Sleep函数&#xff0c;导致UI界面有明显的卡顿 4、总结 VC常用功能开发汇总&a…

COCO_03 制作COCO格式数据集 dataset 与 dataloader

文章目录1 引言2 pycocotools介绍3 Dataset 构建4 Dataloader 构建4.1 解决batch中tensor维度不一致的打包问题4.2 collate_fn()函数分析AppendixA. convert_coco_poly_maskB. COCO_Transform参考1 引言 在之前的文章中&#xff0c;我们认识了COCO数据集的基本格式https://blo…

【设计模式】创建型模式·工厂模式

设计模式学习之旅(四) 查看更多可关注后查看主页设计模式DayToDay专栏 一.引子 需求&#xff1a;设计一个咖啡店点餐系统。 设计一个咖啡类&#xff08;Coffee&#xff09;&#xff0c;并定义其两个子类&#xff08;美式咖啡【AmericanCoffee】和拿铁咖啡【LatteCoffee】&…

NoSQLBooster for MongoDB 8.0.1 Crack

最智能的 MongoDB IDE NoSQLBooster 是 MongoDB Server 3.6-6.0 的跨平台 GUI 工具&#xff0c;它提供内置的 MongoDB 脚本调试器、全面的服务器监控工具、链接流畅查询、SQL 查询、查询代码生成器、任务调度、ES2020 支持和高级 IntelliSense经验。新版本 8.0 现已推出&#x…

Laravel文档阅读笔记-How to Build a Rest API with Laravel: A Beginners Guide①

随着移动端和JavaScript框架的发展&#xff0c;比如React和Vue&#xff0c;Restful风格的API越来越流行。使用Restful风格的好处就是一个后端程序可以与多个版本的前端用户界面关联。 Laravel提供了创建Rest API的环境和生态。 首先得导入依赖包比如Laravel Passport和Larave…

MySQL中给字符串字段加索引

文章目录前言一、前缀索引和普通索引二、前缀索引对覆盖索引的影响三、优化前缀索引前言 学完了MySQL索引部分&#xff0c;我们清楚的认识到给子段添加索引可以快速的进行查询&#xff0c;节约时间。但是索引有很多。那么对于字段怎么加索引&#xff0c;加什么索引。加到索引不…

linux基本功系列之useradd命令实战

文章目录一. useradd 命令介绍二. 语法格式及常用选项三. 参考案例3.1 不加任何参数创建用户3.2 创建不能登录系统且没有家目录的用户3.3 创建一个用户&#xff0c;ID为23333.4 创建一个用户并指定其附加组3.5 创建用户并账户过期时间3.6 与useradd相关的目录文件总结前言&…

InfluxDB的查询优化

首先&#xff0c;在学习influxDB的查询优化之前&#xff0c;我们要先学习下InfluxDB的解释器profiler&#xff08;类似于mysql的Explain语句&#xff0c;不一样的是&#xff0c;sql&#xff0c;hivesql是提前查看执行计划等&#xff0c;Influx是在当前查询的最后一页两张表&…

力扣(LeetCode)382. 链表随机节点(2023.01.15)

给你一个单链表&#xff0c;随机选择链表的一个节点&#xff0c;并返回相应的节点值。每个节点 被选中的概率一样 。 实现 Solution 类&#xff1a; Solution(ListNode head) 使用整数数组初始化对象。 int getRandom() 从链表中随机选择一个节点并返回该节点的值。链表中所有…

WhatsApp居然有3个版本?深度详解区别!外贸圈获客神器用起来!

近两年&#xff0c;外贸圈用WhatsApp来营销获客&#xff0c;越来越火。不少走在前头的外贸人&#xff0c;已经尝到了甜头。但也有不少后来者&#xff0c;站在门外张望的时候&#xff0c;整个人都是蒙圈的。❓听说动不动要整几十个账号&#xff0c;还要花老长时间养号&#xff1…

《Linux Shell脚本攻略》学习笔记-第六章

6.1 简介 你开发应用程序的时间越长&#xff0c;就越能体会到有一个能够跟踪程序修订历史的软件是多重要。 大多数Linux发行版中都包含了Git。如果你的系统中还没有安装&#xff0c;可以通过yum或者apt-get获取。 6.2 创建新的git仓库 git中的所有项目都需要有一个用于保存项目…