Linux 基础¶
工控机上的操作系统,你必须熟悉它¶
你的视觉程序最终跑在一台 Ubuntu 工控机上——它是一台没有显示器、没有键盘的微型电脑,装在机器人里。所有操作都要通过 SSH 在终端里完成。这一章帮你快速掌握 Linux 中最常用、最有用的知识。
Mac 用户请注意
本章内容主要面向远程 Linux 工控机操作。Mac 用户通过 SSH 连接工控机时,以下命令在远程 Linux 上执行。本机 Mac 操作的等价命令会在各节标注。
本章目标
- 理解 Linux 文件系统结构,知道去哪里找设备、改配置
- 掌握文件权限,解决
Permission denied问题 - 熟练使用常用命令,在终端里高效操作
- 看懂 Shell 脚本,理解开机自启是怎么实现的
- 学会 vim,能在远程终端里快速改配置
- 管理进程,学会后台运行、终止、查看程序
- 编写 udev 规则,彻底解决串口设备名漂移问题
1. Linux 文件系统¶
1.1 为什么视觉组需要了解文件系统?¶
你的视觉程序在运行时,要访问摄像头设备、读取配置文件、查找串口、写日志……所有这些都对应着文件系统里的"路径"。找不到设备、权限不够、配置文件位置不对——这些问题 90% 都和文件系统有关。
1.2 核心目录速查¶
/ # 根目录,一切的起点
├── dev/ # 设备文件(摄像头、串口、硬盘都在这里)
├── etc/ # 系统配置文件(udev 规则、网络配置等)
├── home/ # 用户目录(你的代码、项目都在这里)
│ └── navigator/ # 你的用户目录
│ ├── rm_vision/ # 视觉代码仓库
│ └── ...
├── tmp/ # 临时文件,重启后清空
├── usr/ # 用户级程序和库
│ ├── bin/ # 普通命令(ls, grep, vim ...)
│ ├── lib/ # 库文件(.so 文件)
│ └── local/ # 手动安装的程序
├── opt/ # 第三方大型软件
├── proc/ # 进程信息(虚拟文件系统)
└── var/ # 日志、缓存等经常变化的数据
└── log/ # 系统日志
1.3 视觉组最常接触的目录¶
这是最重要的目录之一。Linux 把硬件设备抽象成文件,摄像头、串口、GPIO 全部出现在这里:
# 查看所有串口设备
ls /dev/ttyACM*
ls /dev/ttyUSB*
# 查看摄像头设备
ls /dev/video*
# 读取串口数据(调试时非常有用)
cat /dev/ttyACM0
设备名不固定
/dev/ttyACM0 不会永远是 ttyACM0——重启或重新插拔后,它可能变成 /dev/ttyACM1。这个问题我们会在 udev 规则 那一节解决。
macOS 的设备路径与 Linux 不同,串口设备和摄像头使用不同的命名规则:
# 查看所有串口设备
ls /dev/cu.*
ls /dev/tty.*
# 常见:/dev/cu.usbmodem*, /dev/cu.usbserial*
# 查看摄像头设备
# macOS 不使用 /dev/video*,摄像头通过 AVFoundation 访问
system_profiler SPCameraDataType
串口设备选择
macOS 上 /dev/cu.* 和 /dev/tty.* 都能看到设备,实际连接串口时建议用 /dev/cu.*(cu = callout),它不会阻塞等待设备就绪。
所有系统级配置都在这里,你最常碰到的是:
# udev 规则目录(固定设备名用)
/etc/udev/rules.d/
# 网络配置
/etc/netplan/
# 系统启动服务
/etc/systemd/system/
# 环境变量
/etc/environment
/etc/profile
在视觉组里,你几乎每次配新机器都要改 udev 规则,这个目录要烂熟于心。
你的代码、项目、配置全在这里:
重启后自动清空,适合存放临时数据:
Mac 用户通过 SSH 在远程 Linux 上操作时无需关心这些,但了解 macOS 的对应概念有助于本地开发:
| Linux 路径 | macOS 等价 | 说明 |
|---|---|---|
/dev/ttyACM* |
/dev/cu.usbmodem* |
串口设备,macOS 命名不同 |
/dev/video* |
system_profiler SPCameraDataType |
macOS 无 /dev/video*,通过 AVFoundation 访问 |
/etc/udev/rules.d/ |
无(macOS 没有 udev) | 串口名天然区分,见 udev 节 |
/etc/netplan/ |
无(macOS 用系统偏好设置/networksetup) |
网络配置方式完全不同 |
/etc/environment |
~/.zshrc |
macOS 默认 shell 为 zsh |
/etc/profile |
~/.zshrc 或 ~/.zprofile |
环境变量配置文件 |
apt install |
brew install |
包管理器,需先安装 Homebrew |
systemctl |
launchctl / brew services |
服务管理 |
2. 文件权限¶
2.1 权限的基本概念¶
Linux 的每个文件都有三类权限,分别针对三种身份:
身份 权限
┌──────────┐ ┌──────────┐
│ u: 所有者 │ │ r: 读 │ (4)
│ g: 用户组 │ │ w: 写 │ (2)
│ o: 其他人 │ │ x: 执行 │ (1)
└──────────┘ └──────────┘
查看权限:
$ ls -l /dev/ttyACM0
crw-rw-rw- 1 root dialout 166, 0 Jul 15 10:00 /dev/ttyACM0
# │││││││││
# │││││││└── 其他人: r-- (可读)
# ││││││└─── 用户组: rw- (可读可写)
# │││││└──── 所有者: rw- (可读可写)
# ││││└───── 文件类型: c = 字符设备
2.2 chmod — 修改权限¶
# 数字法(最常用)
chmod 666 /dev/ttyACM0 # 所有人可读可写(rw-rw-rw-)
chmod 755 my_script.sh # 所有者可读写执行,其他人可读执行
chmod 600 ~/.ssh/id_rsa # 只有所有者可读写(私钥文件必须这样)
# 字母法
chmod u+x my_script.sh # 给所有者加执行权限
chmod g+w my_file.txt # 给用户组加写权限
chmod o-r my_secret.txt # 去掉其他人的读权限
视觉组中的实际应用
2.3 chown — 修改所有者¶
# 修改文件所有者
sudo chown navigator:navigator my_file.txt
# 递归修改目录
sudo chown -R navigator:navigator /home/navigator/rm_ws/
2.4 用户组¶
用户组决定了你能不能访问某个设备。这是视觉组最常遇到的权限问题:
# 查看当前用户属于哪些组
groups
# 把用户加入 dialout 组(解决串口权限问题)
sudo usermod -aG dialout navigator
# 加入 video 组(解决摄像头权限问题)
sudo usermod -aG video navigator
# 加入 plugdev 组(解决 USB 设备权限问题)
sudo usermod -aG plugdev navigator
加入用户组后需要重新登录
usermod -aG 只对新的登录会话生效。加入组后,你需要 注销并重新登录,或者重启机器,新的组权限才会生效。
macOS 没有这些用户组
macOS 没有 dialout、video、plugdev 组。串口权限通过临时命令处理:
brew install --cask 安装相关工具后由系统自动管理权限。
3. 常用命令¶
3.1 文件和目录操作¶
# 列出文件
ls # 基本列表
ls -l # 详细信息(权限、大小、日期)
ls -la # 包含隐藏文件(.开头的文件)
ls -lh # 文件大小显示为 KB/MB
# 切换目录
cd /home/navigator/rm_ws/src/ # 绝对路径
cd rm_vision/ # 相对路径
cd .. # 上一级
cd - # 回到上一个目录
cd ~ # 回到家目录
# 创建/删除
mkdir -p src/my_package/ # 递归创建目录
rm old_file.txt # 删除文件
rm -rf build/ # 递归强制删除(慎用!)
# 复制/移动
cp config.yaml config.yaml.bak # 备份配置文件
mv old_name.cpp new_name.cpp # 重命名
3.2 查看文件内容¶
# 查看整个文件
cat /etc/os-release # 查看系统版本
# 查看前/后几行
head -20 my_code.cpp # 前20行
tail -20 my_code.cpp # 后20行
tail -f /var/log/syslog # 实时跟踪日志更新(Ctrl+C 退出)
# 分页查看
less my_code.cpp # 空格翻页,q 退出
在视觉组中怎么用
3.3 grep — 文本搜索¶
grep 是你用得最多的命令之一——在代码里找关键词、在日志里找错误:
# 在当前目录及子目录中搜索(最常用)
grep -r "Topic" . # 搜索所有包含 "Topic" 的文件
grep -rn "serial_port" . # 显示行号
grep -rn --include="*.cpp" "class " . # 只在 .cpp 文件中搜索
grep -rn --include="*.yaml" "topic" . # 只在配置文件中搜索
# 忽略大小写
grep -rni "error" .
# 反向搜索(找不含某个关键词的行)
grep -v "^#" config.yaml # 过滤掉注释行,看有效配置
实战:定位问题
3.4 find — 查找文件¶
# 按文件名查找
find / -name "ttyACM*" 2>/dev/null # 在整个系统中找串口设备
find . -name "*.yaml" # 在当前目录找所有 yaml 文件
find . -name "*.cpp" -newer old.cpp # 找比 old.cpp 更新的 cpp 文件
# 按类型查找
find . -type d -name "build" # 只找目录
find . -type f -name "*.so" # 只找文件
3.5 apt / dpkg — 包管理¶
工控机上装软件、装库全靠这两个命令:
# apt:从网络安装(最常用)
sudo apt update # 更新软件列表
sudo apt upgrade # 升级所有已安装的包
sudo apt install vim # 安装单个软件
sudo apt install libopencv-dev # 安装 OpenCV 开发库
sudo apt remove vim # 卸载软件
sudo apt autoremove # 清理不再需要的依赖
# dpkg:管理本地 .deb 安装包
sudo dpkg -i package.deb # 安装本地 deb 包
dpkg -l | grep opencv # 查看已安装的 opencv 相关包
dpkg -L libopencv-dev # 查看某个包装了哪些文件
macOS 等价:Homebrew
macOS 没有 apt,使用 Homebrew 作为包管理器(需先安装:/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"):
# Homebrew 等价命令对照
brew update # ≈ sudo apt update
brew upgrade # ≈ sudo apt upgrade
brew install vim # ≈ sudo apt install vim
brew install opencv # ≈ sudo apt install libopencv-dev
brew uninstall vim # ≈ sudo apt remove vim
brew autoremove # ≈ sudo apt autoremove
brew list | grep opencv # ≈ dpkg -l | grep opencv
brew info opencv # ≈ dpkg -L libopencv-dev(查看包信息)
本地开发 vs 远程部署
本地 Mac 上用 Homebrew 安装的软件仅供本地开发/调试使用,最终部署仍需在远程 Linux 工控机上用 apt 安装对应版本。
3.6 命令组合 — 管道与重定向¶
管道 | 把前一个命令的输出,作为后一个命令的输入:
# 找到所有进程中的 ros2 相关进程
ps aux | grep ros2
# 列出串口设备,只看 ttyACM 开头的
ls /dev/ | grep ttyACM
# 查看代码行数
find . -name "*.cpp" | xargs wc -l
# 把输出保存到文件
ros2 topic echo /detector/armors > armor_log.txt
4. Shell 脚本基础¶
4.1 什么是 Shell 脚本?¶
Shell 脚本就是把多条终端命令写进一个文件,然后一次性执行。视觉组里最典型的例子就是 开机自启脚本。
4.2 变量¶
#!/bin/bash
# 定义变量(等号两边不能有空格!)
NAME="navigator"
ROS_DISTRO="humble"
WS_PATH="/home/navigator/rm_ws"
# 使用变量
echo "Hello, $NAME"
echo "ROS 版本: ${ROS_DISTRO}"
# 读取命令输出
CURRENT_DATE=$(date +%Y-%m-%d)
echo "今天是: $CURRENT_DATE"
4.3 条件判断¶
#!/bin/bash
# 判断文件是否存在
if [ -f "/dev/ttyACM0" ]; then
echo "串口设备已连接"
else
echo "串口设备未找到,请检查 USB 线"
exit 1
fi
# 判断目录是否存在
if [ -d "$HOME/rm_ws/src/rm_vision" ]; then
echo "视觉代码仓库已存在"
fi
# 比较字符串
DEVICE="ttyACM0"
if [ "$DEVICE" = "ttyACM0" ]; then
echo "这是主串口"
fi
# 数值比较
COUNT=5
if [ $COUNT -gt 3 ]; then
echo "进程数大于 3"
fi
常用判断条件:
| 条件 | 含义 |
|---|---|
-f file |
文件存在且是普通文件 |
-d dir |
目录存在 |
-e path |
路径存在(文件或目录) |
-x file |
文件可执行 |
-z string |
字符串为空 |
-n string |
字符串不为空 |
= |
字符串相等 |
-gt / -lt |
大于 / 小于(数值) |
4.4 循环¶
#!/bin/bash
# for 循环:遍历文件
for file in /dev/ttyACM*; do
echo "找到设备: $file"
done
# for 循环:数字范围
for i in $(seq 1 3); do
echo "尝试第 $i 次..."
if [ -f "/dev/ttyACM0" ]; then
echo "设备就绪"
break
fi
sleep 1
done
# while 循环:持续监控
while true; do
if ! pgrep -x "vision_node" > /dev/null; then
echo "视觉节点挂了,正在重启..."
cd /home/navigator/rm_ws
source install/setup.bash
ros2 run rm_vision vision_node &
fi
sleep 5
done
4.5 函数¶
#!/bin/bash
# 定义函数
start_vision() {
echo "[$(date)] 正在启动视觉系统..."
cd /home/navigator/rm_ws
source install/setup.bash
ros2 launch rm_vision vision.launch.py
}
stop_vision() {
echo "[$(date)] 正在停止视觉系统..."
pkill -f "vision_node"
pkill -f "rm_vision"
}
check_device() {
local device=$1
if [ -e "$device" ]; then
echo "[OK] $device 存在"
return 0
else
echo "[FAIL] $device 不存在"
return 1
fi
}
# 使用函数
check_device "/dev/ttyACM0"
if [ $? -eq 0 ]; then
start_vision
fi
4.6 完整示例:看懂 autostart.sh¶
这是一个典型的视觉系统开机自启脚本:
#!/bin/bash
# ============================================
# 视觉系统自启动脚本
# 放在 /home/navigator/autostart.sh
# ============================================
# 配置区(改成你自己的路径)
WORKSPACE="/home/navigator/rm_ws"
LAUNCH_FILE="rm_vision vision.launch.py"
LOG_DIR="/home/navigator/logs"
LOG_FILE="$LOG_DIR/vision_$(date +%Y%m%d_%H%M%S).log"
# 创建日志目录
mkdir -p "$LOG_DIR"
# 等待系统完全启动
echo "[$(date)] 等待系统启动..." | tee -a "$LOG_FILE"
sleep 10
# 检查串口设备
if [ ! -e "/dev/ttyACM0" ]; then
echo "[$(date)] 串口设备未找到,等待 5 秒..." | tee -a "$LOG_FILE"
sleep 5
fi
# 进入工作空间,加载环境
cd "$WORKSPACE" || { echo "工作空间不存在"; exit 1; }
source /opt/ros/humble/setup.bash
source install/setup.bash
# 启动视觉系统,输出重定向到日志文件
echo "[$(date)] 启动视觉系统..." | tee -a "$LOG_FILE"
ros2 launch $LAUNCH_FILE 2>&1 | tee -a "$LOG_FILE"
逐段理解
#!/bin/bash— 告诉系统用 bash 来执行这个文件mkdir -p—-p表示如果目录已存在不报错|| { ...; exit 1; }— 如果 cd 失败,执行花括号里的命令然后退出source ...— 加载 ROS2 环境变量,不执行这步就找不到ros2命令2>&1 | tee— 把标准输出和错误输出都同时显示在屏幕和写入日志文件
5. vim 编辑器¶
5.1 为什么学 vim?¶
你通过 SSH 连接工控机时,很可能没有图形界面。需要快速改配置文件、修启动脚本,vim 是最可靠的选择——几乎所有 Linux 系统都预装了它。
5.2 三种模式¶
┌──────────┐ i/a/o ┌──────────┐ Esc ┌──────────┐
│ 普通模式 │ ──────────→ │ 插入模式 │ ───────→ │ 普通模式 │
│ (浏览/操作) │ ←────────── │ (输入文字) │ │ │
└──────────┘ └──────────┘ └─────┬────┘
│ │
│ : │
▼ │
┌──────────┐ ┌──────────┐ │
│ 命令模式 │ ──────────→ │ 普通模式 │ ←────────────────┘
│ (保存/退出) │ │ │
└──────────┘ └──────────┘
5.3 最小必会操作¶
# 打开文件
vim config.yaml
# 进入插入模式(开始编辑)
i # 在光标前插入
a # 在光标后插入
o # 在下面新开一行
# 回到普通模式
Esc
# 保存/退出(先按 Esc,再输入冒号命令)
:w # 保存
:q # 退出(如果有未保存修改会提示)
:wq # 保存并退出
:q! # 强制退出不保存
# 普通模式下的基本操作
dd # 删除当前行
yy # 复制当前行
p # 粘贴
u # 撤销
/keyword # 搜索关键词(按 n 跳到下一个)
视觉组中最常见的 vim 场景
vim 新手急救
不知道自己在什么模式?按几下 Esc,然后输入 :wq 保存退出——这在任何模式下都能安全退出。
6. 进程管理¶
6.1 查看进程¶
# 查看所有进程
ps aux
# 只看和 ros2 相关的进程
ps aux | grep ros2
# 树状显示进程关系
ps auxf | grep ros2
# macOS 不支持 ps auxf 的 f 选项,可用 brew install pstree 后用 pstree 查看进程树
# 实时监控(类似任务管理器,按 q 退出)
top
htop # 更好用的版本(需要 sudo apt install htop)
6.2 终止进程¶
# 优雅终止(发送 SIGTERM)
kill <PID> # PID 用 ps aux 查看
# 强制终止(发送 SIGKILL,最后手段)
kill -9 <PID>
# 按名字杀进程
pkill -f "vision_node" # 终止包含 vision_node 的进程
pkill -f "ros2" # 终止所有 ros2 进程
# 终止整个 ROS2 系统
ros2 daemon stop
慎用 kill -9
kill -9 是强制杀死进程,进程来不及保存数据就被终止。正常使用应该先 kill(不带 -9),等几秒看进程是否退出,再决定要不要强制杀。
6.3 后台运行¶
视觉程序需要在后台持续运行,SSH 断开后也不能停:
# 最简单:在命令末尾加 &
ros2 launch rm_vision vision.launch.py &
# 注意:SSH 断开后,这个进程也会被杀掉!
# 用 nohup 防止 SSH 断开导致进程退出
nohup ros2 launch rm_vision vision.launch.py &
# 默认输出写入 nohup.out
# 指定日志文件
nohup ros2 launch rm_vision vision.launch.py > vision.log 2>&1 &
6.4 screen — 终端复用器(强烈推荐)¶
screen 让你创建一个"持久化终端"——即使 SSH 断开,里面运行的程序也不会停。重连后可以重新接回原来的终端。
macOS 用户推荐 tmux
macOS 上 screen 已被弃用,推荐使用功能更强大的 tmux(brew install tmux):
# 创建一个新的 screen 会话
screen -S vision
# 在 screen 里正常操作,启动视觉程序
cd ~/rm_ws && source install/setup.bash
ros2 launch rm_vision vision.launch.py
# 断开 screen(不终止里面运行的程序)
# 按 Ctrl+A,然后按 D
# 查看所有 screen 会话
screen -ls
# 重新连接到之前的会话
screen -r vision
# 终止 screen 会话
# 在 screen 里输入 exit,或者:
screen -X -S vision quit
工控机上的典型工作流
# 1. SSH 连接工控机
ssh navigator@192.168.1.10
# 2. 创建 screen 会话运行视觉程序
screen -S vision
cd ~/rm_ws && source install/setup.bash
ros2 launch rm_vision vision.launch.py
# 按 Ctrl+A, D 断开
# 3. 再创建一个 screen 做其他事
screen -S debug
# 在这里看日志、调参数...
# 按 Ctrl+A, D 断开
# 4. 断开 SSH
exit
# 5. 第二天重新连上,接回视觉程序
ssh navigator@192.168.1.10
screen -r vision
# 视觉程序一直在跑,日志还在
6.5 ROS2 相关的进程管理¶
# 查看所有正在运行的节点
ros2 node list
# 查看节点的详细信息(发布/订阅的话题)
ros2 node info /vision_node
# 查看话题列表
ros2 topic list
# 查看话题是否在发布数据
ros2 topic hz /detector/armors
# 手动终止整个 ROS2 launch
pkill -f "ros2 launch"
7. udev 规则¶
7.1 为什么需要 udev 规则?¶
macOS 没有 udev
macOS 没有 udev 系统。串口设备名天然区分(/dev/cu.usbmodem*、/dev/cu.usbserial*),通常不会像 Linux 那样漂移。如需固定名称,可以用 ln -s 创建符号链接。查看所有 USB 设备:system_profiler SPUSBDataType。
这是视觉组最常遇到、也最让新手困惑的问题之一。
问题:工控机上有多个 USB 设备(裁判系统串口、电机调试串口等),Linux 给它们分配的名字是 /dev/ttyACM0、/dev/ttyACM1……但每次重新插拔或重启,名字可能互换。你的代码写死读 /dev/ttyACM0,结果今天连的是裁判系统,明天重启后连的可能变成了调试串口。
解决:用 udev 规则,根据设备的 供应商 ID(Vendor ID) 和 产品 ID(Product ID) 给设备固定一个名字。
7.2 第一步:找到设备的 ID¶
输出类似:
Bus 001 Device 003: ID 1a86:7523 QinHeng Electronics CH340 serial adapter
Bus 001 Device 004: ID 0483:5740 STMicroelectronics STM32 Virtual COM Port
ID 1a86:7523 就是 VendorID:ProductID。
也可以用 udevadm 获取更详细的信息:
找类似这样的输出:
7.3 第二步:创建 udev 规则文件¶
写入以下内容(根据你的设备修改):
# 裁判系统串口 — 固定为 /dev/referee
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", MODE="0666", SYMLINK+="referee"
# 调试用的 CH340 串口 — 固定为 /dev/debug_serial
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE="0666", SYMLINK+="debug_serial"
# 如果有多个相同型号的设备,用 serial 号区分
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ATTRS{serial}=="368D38643337", MODE="0666", SYMLINK+="referee"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ATTRS{serial}=="368D38643338", MODE="0666", SYMLINK+="gun_serial"
规则文件各字段含义:
| 字段 | 含义 |
|---|---|
SUBSYSTEM=="tty" |
只匹配串口设备 |
ATTRS{idVendor} |
供应商 ID(lsusb 查到的前半段) |
ATTRS{idProduct} |
产品 ID(lsusb 查到的后半段) |
ATTRS{serial} |
序列号(区分同型号设备) |
MODE="0666" |
设置权限为所有人可读可写 |
SYMLINK+="referee" |
创建符号链接 /dev/referee 指向这个设备 |
7.4 第三步:生效规则¶
# 重新加载 udev 规则
sudo udevadm control --reload-rules
sudo udevadm trigger
# 验证:拔掉设备再插上
ls -l /dev/referee
# 应该显示 -> ttyACM0 或 ttyACM1(不管哪个,名字都是 referee)
7.5 在代码中使用固定设备名¶
效果
无论设备插在哪个 USB 口,无论重启多少次,你的代码只需要读 /dev/referee,udev 会自动帮你找到正确的设备。
7.6 常见问题排查¶
# 规则写好了但没生效?
# 1. 检查语法有没有写错
cat /etc/udev/rules.d/99-serial.rules
# 2. 确认规则文件名以数字开头(数字决定加载顺序)
ls /etc/udev/rules.d/
# 3. 确认规则文件权限
ls -l /etc/udev/rules.d/99-serial.rules
# 应该是 -rw-r--r--
# 4. 查看 udev 日志
udevadm monitor --environment --udev
# 5. 测试规则是否匹配某个设备
udevadm test /sys/class/tty/ttyACM0
两个相同型号设备怎么区分?
如果你有两个完全一样的 STM32 串口设备,idVendor 和 idProduct 完全相同,必须用 serial 号区分:
综合练习¶
动手试试
在 SSH 连接到工控机后,完成以下操作:
练习 1:熟悉环境
# 查看系统信息
cat /etc/os-release
uname -a
# 查看家目录结构
ls -la ~
# 查看有哪些串口设备
ls /dev/tty*
# 查看当前用户属于哪些组
groups
练习 2:代码搜索
# 在视觉代码中找到所有 .launch.py 文件
find ~/rm_ws/src -name "*.launch.py"
# 搜索代码里用了哪些 ROS2 topic
grep -rn --include="*.cpp" "create_publisher" ~/rm_ws/src/
# 搜索配置文件中的串口设置
grep -rn --include="*.yaml" "serial" ~/rm_ws/src/
练习 3:进程管理
速查表¶
常用命令速查
| 场景 | 命令 |
|---|---|
| 查看串口设备 | ls /dev/ttyACM* ls /dev/ttyUSB* |
| 给串口权限 | sudo chmod 666 /dev/ttyACM0 |
| 搜索代码 | grep -rn "关键词" . |
| 查找文件 | find . -name "*.cpp" |
| 后台运行 | nohup command & |
| 创建 screen | screen -S name |
| 接回 screen | screen -r name |
| 查看进程 | ps aux \| grep ros2 |
| 终止进程 | pkill -f "process_name" |
| 查看 ROS2 节点 | ros2 node list |
| 实时看日志 | tail -f /path/to/log |
| 编辑文件 | vim file (i 插入, Esc, :wq 保存退出) |
| 装软件 | sudo apt install package |
| 改权限 | chmod 755 file |
| 改所有者 | sudo chown user:group file |