三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

shell和github相关

shell和github相关

shell和github相关

显存nvidia-smi

import **os** for j in **range**(1000000000000): kk = "nvidia-smi|grep \"MiB / 24564MiB\" >/home/kkk.txt" **os**.**system**(kk) with **open**("/home/kkk.txt", 'r') as obj: lll = obj.**read**() lll = lll.**split**(" ") for i in lll: if 'MiB' in i: www = **int**(i.**replace**("MiB", "")) break if www < 1000: **time**.**sleep**(30) break else: **print**(f"waiting {www}, {j}") **time**.**sleep**(100) l = 0

Git 删除 commit 区分场景(⚠️ 谨慎操作!已经push远端绝对不要乱用)

先分清两种场景

  1. commit 仅本地,尚未 push 到远程仓库(安全)

  2. commit 已经推送到远端 origin(高危,团队协作严禁随便强制推送)

场景1:仅本地,还没push(最常用)

① 保留代码,撤销commit(推荐,代码不动,只是删掉提交记录)

# HEAD~1 删除最近1次commit;HEAD~3 删除最近3次 git reset --soft HEAD~1
  • --soft:文件改动保留在暂存区

  • --mixed(默认不加参数):改动保留在工作区,取消暂存

git reset HEAD~1

② 彻底删除commit +丢弃所有代码改动(危险!数据丢失)

git reset --hard HEAD~1

HEAD~1 = 上一个提交

HEAD~2 = 往上两个提交

场景2:已经 push 到远程仓库(单人仓库可用,多人协作禁止)

# 本地先回退 git reset --hard HEAD~1 # 强制覆盖远端 git push origin 你的分支名 --force-with-lease

--force-with-lease--force安全一点,会检查远端是否别人新提交代码

额外:删除指定某一条历史commit(中间某一条,不是最后)

使用交互式rebase

git rebase -i HEAD~5

弹出编辑器,把想要删除的那条前面pick修改成drop,保存退出。

常用示例

示例1:删除最近1条commit,代码保留

git reset --soft HEAD~1

示例2:删除最近2条commit,彻底丢弃改动

git reset --hard HEAD~2

⚠️ 重要红线

  1. 如果分支多人共同开发,不要 hard reset + force push,会覆盖别人提交!

  2. hard reset 丢失的代码很难找回,操作前确认不需要改动

  3. 如果误操作想找回丢失commit:git reflog查看历史HEAD编号,再次reset回去

你告诉我两点,我给你精确命令:

  1. 需要删除最近几个commit?

  2. 是否已经git push推送到远端?

方案1:build.sh 完整脚本

#!/bin/bash # 判断第一个传入参数 $1 是否等于 onnx if [ "$1" = "onnx" ]; then # 相等则传入编译参数 cmake -DCMAKE_BUILD_PLATFORM=ONNX .. else # 可选:不相等时正常编译/提示 echo "未传入onnx参数,不开启ONNX平台编译" cmake .. fi

使用方式

# 触发传入ONNX编译参数 ./build.sh onnx # 不触发 ./build.sh tensorrt

方案2:如果你脚本里是先判断字符串变量(适配你描述场景)

#!/bin/bash input_str="$1" target_str="onnx" if [ "$input_str" = "$target_str" ]; then echo "参数匹配,开启ONNX编译" cmake -DCMAKE_BUILD_PLATFORM=ONNX .. else cmake .. fi

关键点说明

  1. 字符串比较规范

    • [ "$1" = "onnx" ]:两边必须加双引号,防止参数为空、带空格时报语法错误

    • =前后必须有空格,少空格会直接报错

  2. CMake 参数传递逻辑

cmake -DXXX=YYY是标准传参写法,大写 ONNX 和脚本小写 onnx 仅做标识区分不影响逻辑

  1. 完整编译流程补充(带构建目录)
#!/bin/bash set -e # 入参判断 if [ "$1" = "onnx" ]; then PLATFORM_ARG="-DCMAKE_BUILD_PLATFORM=ONNX" else PLATFORM_ARG="" fi # 创建构建目录编译 mkdir -p build && cd build cmake $PLATFORM_ARG .. make -j$(nproc)

报错分两类:链接缺失OpenCV aruco库 + printf格式错误,分开修复

一、致命错误:找不到 libopencv_aruco.so(编译失败根源)

No rule to make target '../../install/lib/libopencv_aruco.so', needed by 'fcos3d_test'

原因

  1. 你的OpenCV安装包未编译/未安装 aruco 模块

  2. CMakeLists.txt 硬编码链接opencv_aruco,但本地库文件不存在;

  3. OpenCV安装路径../../install/下缺少该so文件。

修复方案

方案1:不需要aruco模块 → CMakeLists删除对应链接

找到CMakeLists.txt里类似这一行:

# 原错误代码 find_package(OpenCV REQUIRED) target_link_libraries(fcos3d_test ${OpenCV_LIBS}) # 或手动写了 opencv_aruco

修改:

  • 方式A:只引入需要的OpenCV组件,排除aruco
find_package(OpenCV REQUIRED COMPONENTS core highgui imgproc imgcodecs)
  • 方式B:如果手动写死链接列表,删掉opencv_aruco
# 原来 target_link_libraries(fcos3d_test opencv_core opencv_aruco opencv_highgui) # 修改后 target_link_libraries(fcos3d_test opencv_core opencv_highgui)
方案2:项目必须使用aruco → 重新编译带aruco的OpenCV

编译OpenCV时开启aruco模块:

cmake -DBUILD_opencv_aruco=ON -DCMAKE_INSTALL_PREFIX=/home/Desktop/fcos3d_deploye/install .. make -j$(nproc) make install

编译安装完成后,重新执行你的./build.sh onnx编译项目。

二、警告(不阻断编译,但代码bug,建议修复)printf参数不匹配

报错代码行:

printf("[ test.cpp ]: detection time consumption is %f ms ! \n", i, time_diff);

问题分析

  1. 格式化字符串只有1个%f,但传入了两个变量i(int)、time_diff

  2. %f对应浮点,却把int类型i填到第一个占位符,类型不匹配。

两种修复写法

写法1:同时打印循环序号i + 耗时
printf("[ test.cpp ]: frame %d detection time consumption is %f ms ! \n", i, time_diff);
写法2:只打印耗时,删掉多余i
printf("[ test.cpp ]: detection time consumption is %f ms ! \n", time_diff);

完整重新编译步骤

  1. 修改完 CMakeLists.txt + testOnnx.cpp

  2. 清空旧构建缓存

rm -rf build mkdir build && cd build
  1. 执行你的编译脚本
cd .. ./build.sh onnx

补充排查点

如果修改后仍然报找不到aruco:

  1. 检查ls /home/Desktop/fcos3d_deploye/install/lib/确认有无libopencv_aruco.so

  2. 确认CMake中OpenCV路径指向正确的install目录,不要混用系统OpenCV和本地编译OpenCV;

  3. 若使用本地自定义OpenCV,CMake需指定路径:

set(OpenCV_DIR "/home/Desktop/fcos3d_deploye/install/lib/cmake/opencv4") find_package(OpenCV REQUIRED)

报错根因分析

报错EADDRINUSE address already in use 18092明明没有进程监听18092却报端口占用,99%是两种情况:

  1. 上次训练进程异常崩溃(Ctrl+C/程序crash),TCP套接字进入TIME_WAIT滞留60秒,内核仍占用端口,新进程无法bind;

  2. 残留孤儿python子进程/多进程spawn僵尸进程,肉眼看不见监听,但后台持有端口。

日志关键点:你用硬编码固定端口tcp://``localhost:18092,每次重启都会抢同一个端口,极易触发冲突。

一、先排查并清理端口(立刻生效)

1. 查找占用18092的进程(含僵尸进程)

# 查找监听LISTEN的进程 ss -tulnp | grep 18092 # 查找所有和18092相关的TCP连接(包含TIME_WAIT) ss -tan | grep 18092 # 一键杀掉所有占用18092的进程

2. 清理所有残留python训练进程(根治僵尸进程)

# 杀掉所有相关python分布式进程 pkill -f "ddp_trainer|torch.distributed" # 强制清理所有python pkill -9 python3

执行完上面命令后,等待10秒再启动程序,大概率直接恢复。

二、永久解决方案(推荐,分3种方案)

方案1:启动时随机动态端口(最简单,改启动命令)

不写死18092,每次启动自动分配空闲端口,彻底规避冲突。

方式A:环境变量随机端口(推荐)
# 每次启动随机端口 MASTER_PORT=$((18000 + RANDOM % 1000)) python train.py
方式B:代码内自动获取空闲端口(彻底不用管端口)

修改ddp_trainer.pydist_url硬编码逻辑,替换为自动获取端口:

import socket # 自动找空闲端口 def get_free_port(): sock = socket.socket() sock.bind(("127.0.0.1", 0)) port = sock.getsockname()[1] sock.close() return port # 替换原来的硬编码tcp://localhost:18092 free_port = get_free_port() dist_url = f"tcp://localhost:{free_port}"

方案2:内核开启端口复用(解决TIME_WAIT残留)

临时生效(重启失效):

sudo sysctl -w net.ipv4.tcp_tw_reuse=1 sudo sysctl -w net.ipv4.tcp_fin_timeout=10

永久生效:

echo "net.ipv4.tcp_tw_reuse = 1" | sudo tee -a /etc/sysctl.conf echo "net.ipv4.tcp_fin_timeout = 10" | sudo tee -a /etc/sysctl.conf sudo sysctl -p

作用:允许新进程复用处于TIME_WAIT的端口,不用等60秒释放。

方案3:代码增加SO_REUSEADDR(PyTorch底层TCPStore复用)

如果不方便改端口,可在初始化分布式前手动设置socket复用,适用于单机单卡训练场景。

三、补充说明日志里的无关警告

WARNING:hat.utils.setup_env:The file `/etc/nccl.conf` does not exist.

这条完全不影响运行,只是缺少NCCL自定义配置文件,不用处理。

四、一键启动脚本(集成自动清端口+随机端口)

你可以写一个启动脚本,每次训练前自动清理端口、随机分配端口,一劳永逸:

#!/bin/bash # train.sh PORT=18092 # 清理占用端口进程 sudo lsof -ti:$PORT | xargs -r kill -9 # 随机端口启动 MASTER_PORT=$((18000 + RANDOM % 2000)) echo "使用端口: $MASTER_PORT" python train.py

执行:bash train.sh

五、快速验证步骤

  1. 执行清理命令sudo lsof -ti:18092 | xargs -r kill -9

  2. 用随机端口启动MASTER_PORT=$((18000 + RANDOM % 1000)) python train.py

  3. 若不再报错,说明是固定端口TIME_WAIT/僵尸进程导致,后续使用随机端口方案即可永久解决。

Nmap 查找局域网内带SSH(22端口)的嵌入式板子完整方案

一、先确认本机局域网网段

Windows

ipconfig

找到以太网适配器/WLAN的IPv4,如192.168.1.100,网段就是192.168.1.0/24

Linux / Ubuntu

ifconfig # 或 ip a

获取本机网段,例:192.168.0.0/24

二、全网段扫描(只探测22端口,速度快,适合找嵌入式)

1. 最简命令(推荐,只扫22,存活主机优先)

# 替换成你的网段,如192.168.1.0/24 nmap -T4 -p 22 192.168.1.0/24

参数说明:

  • -T4:加速扫描,不影响设备

  • -p 22:仅扫描SSH端口,减少流量、不骚扰板子

  • /24:扫该网段下全部254台设备

2. 先ping存活主机再扫22(更省时间)

nmap -sn 192.168.1.0/24 # 先找出所有开机设备 nmap -T4 -p 22 --open 192.168.1.0/24 # 只输出22开放的IP

--open只显示端口开放的设备,过滤大量无意义结果

3. 静默扫描(不触发板子防火墙告警)

nmap -T2 -p 22 -sS 192.168.1.0/24
  • -T2低速温和扫描

  • -sS半连接扫描,日志痕迹少

三、进阶:识别设备类型(区分电脑/嵌入式开发板)

嵌入式板子SSH banner通常带Linux、ARM、Buildroot、OpenWrt、Ubuntu ARM等标识

# 扫描同时抓取SSH服务版本信息 nmap -T4 -p 22 -sV 192.168.1.0/24

输出会显示:

22/tcp open ssh OpenSSH 8.4p1 Ubuntu 5ubuntu2.3 (Ubuntu Linux; protocol 2.0)

看到ARM、Buildroot、OpenWrt即为目标板子

四、Windows无nmap?替代方案

  1. 安装Nmap官网安装包

  2. PowerShell简易全网ping探测(先筛存活IP)

1..254 | ForEach-Object { Test-Connection 192.168.1.$_ -Count 1 -TimeoutSeconds 1 }

五、常见问题

  1. 扫描没结果

    • 板子和电脑不在同一个路由器/WiFi;

    • 板子防火墙拦截ICMP(ping),加-Pn强制跳过ping直接扫端口:

      nmap -T4 -p 22 -Pn 192.168.1.0/24
  2. 扫描太慢

    • 缩小网段范围,或用-T5极速扫描(局域网内可用)
  3. 板子22端口被修改

嵌入式有时改成2222、2345等,可多端口扫描:

nmap -T4 -p 22,2222,2345 192.168.1.0/24

六、找到IP后连接ssh

ssh root@192.168.1.123

嵌入式默认账号常见:rootadmin,密码多为root123456、空密码。

需要我根据你的电脑IP帮你生成一条可以直接复制运行的完整扫描命令吗?你发一下本机ip即可。

SSH 免密自动登录(最常用两种方案)

方案1:密钥免登(标准、推荐,所有Linux/ssh都支持)

原理:本地生成密钥对,公钥放到远程机器~/.ssh/authorized_keys

1. 生成密钥(本地终端,Windows Git Bash / WSL / Mac / Linux)

# 一路回车,不要设置密码(实现完全自动登录) ssh-keygen

如果已有密钥不想覆盖:ssh-keygen -f ~/.ssh/id_ssh_target

2. 推送公钥到远程服务器

# ssh-copy-id 一键推送(有这个命令优先用) ssh-copy-id username@远程IP

没有 ssh-copy-id(Windows)手动命令:

cat ~/.ssh/id_rsa.pub | ssh username@IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

3. 测试免密登录

ssh username@IP

无需输入密码即成功。


方案2:VSCode Remote-SSH 自动登录(你大概率需要这个!)

如果你是 VSCode 通过 SSH 远程开发,直接配置~/.ssh/config,不用每次输地址账号

1. 创建/编辑本地ssh配置文件

Windows路径:****C:\Users\你的用户名\.ssh\config

Linux/Mac:****~/.ssh/config

写入模板:

Host myserver HostName 192.168.1.100 User root Port 22 IdentityFile ~/.ssh/id_rsa

参数说明:

  • Host myserver:别名,之后直接ssh myserver连接

  • HostName:远程IP

  • User:登录用户名

  • Port:ssh端口(默认22可删掉)

  • IdentityFile:私钥路径(密钥免登必填)

保存后 VSCode Remote SSH 侧边栏会自动识别这个主机,点击直接连接。

⚠️权限注意:

Linux/Mac 本地.ssh文件夹权限700,私钥id_rsa600

chmod 700 ~/.ssh chmod 600 ~/.ssh/id_rsa

❗ 不推荐方案:密码明文自动登录

ssh 原生不支持明文密码登录,需要工具sshpass,不安全(密码明文保存),仅内网临时测试用:

sshpass -p "你的密码" ssh username@ip

常见排错

  1. 密钥配置完成依旧提示输密码

    • 远程服务器~/.ssh权限过大;

    • sshd 配置禁止密钥登录:检查/etc/ssh/sshd_config

      PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
  2. VSCode Remote SSH 识别不到配置

确保 config 文件没有后缀,编码 UTF-8,换行使用 LF。


告诉我两点,我直接给你写好完整可用的 config:

1)本地系统:Windows(cmd/powershell)还是 WSL / Linux?

2)远程 IP、用户名、端口号。

← 返回列表