系统常用命令及快捷键

本文最后更新于 2025年7月2日 晚上

本文主要分享了自己在使用Linux和Windows系统过程中常用的命令及快捷键。

注意中文和英文字符-

Linux

Win = Super

快捷键

一般

快捷键 作用
Win+L 锁屏
Ctrl+Alt+T 新建终端
Ctrl+Alt+A(自定) flameshot 截图
Ctrl+Alt+F(自定) fsearch 搜索文件
Ctrl+Shift+N 新建文件夹
Win+I(自定义) 打开设置中心
Ctrl+L 全选文件夹路径
F2 文件(夹)重命名
Win 活动大纲
Win+Tab/Alt+Tab 切换应用程序
Ctrl+Alt+上/下箭头,点击桌面左上角的“Activities” 切换工作区(同一屏幕的全部内容)
Alt+Enter 查看选择文件/文件夹的属性,代替单击右键选择属性
Ctrl+1/2 改变文件夹视图查看方式,图标视图/列表视图
Ctrl+H 显示隐藏文件
双击Ctrl(自定) 打开uTools
启动位于任务栏的程序 Win + 数字键

窗口

快捷键 作用
Win+E(自定义) 新建文件夹窗口
win+H 隐藏窗口
Win+D 隐藏或显示全部应用窗口
Win+A 显示应用程序菜单
Super+箭头 移动窗口位置(左/右:贴左/右;上:最大化;下:恢复)
Ctrl+W 关闭标签页
Ctrl+Q/Alt+F4 (强制)关闭应用程序(窗口)。ALT+F4是基于任务管理器连接结束进程项,CTRL+Q只是关闭的快捷键
Alt+空格(自定) 激活窗口菜单(内含置顶选项,也适用于没有系统标题栏的应用)
Win+Shift+向上/下翻页 将窗口上/下移一个工作区
Win+Shift+上/下/左/右箭头 将窗口上/下/左/右移一个显示器
Alt+F7(自定义) 使用键盘方向键移动窗口,按住Shift键快速贴边,按Enter键确认

目录

快捷键 作用
Backspace 返回上一级目录
Alt+左箭头 回退(搭配Backspace回到下一级目录)
Alt+右箭头 前进(只能响应回退操作)

打开文件夹之后,按backspace删除键就可以返回上一级;或者Alt+←也是可以返回上一级,用Alt+←返回上一级后,按Alt+→键就可以倒退回去一级。

鼠标

  1. 直接拖拉在最大化时的窗口标题可以还原窗口大小,再拖放回去就最大化。
  2. 在音量控制处用鼠标滚轮滚动可以直接调整音量,在任务栏中滚动滚轮可以切换任务栏,工作区则切换工作区。
  3. 工作区里的小窗口可以在不同工作区内拖拉,即移动到另一个工作区的功能。
  4. 按住 Shift 拖动窗口可以吸附上下边缘的移动。
  5. 水平滚动文件,请在按住 Shift 的同时转动鼠标滚轮。
  6. 双击选中词,三击选中整句。
  7. 按住Alt,鼠标可以选中带链接的内容(而不打开链接)。
  8. 按住Shift,鼠标在开头和结尾点击,可以选中全文(不用拖动了)。
  9. 拖动选中可直接完成复制粘贴的操作(对于某些禁止复制粘贴的网站)。
  10. 在Win11,按住Shift,点击鼠标右键,呼出旧版菜单。
  11. 鼠标中间有快捷关闭的功能。

路径

  1. 对于在.zshrc等文件中使用export命令时,举例说明:

    1
    2
    3
    4
    export PATH="$PATH:/new_path"
    # 1. 路径之间用英文:分隔,中间不需要加空格。
    # 2. 加双引号可以避免潜在的解析错误(空格、特殊字符)。
    # 3. $PATH放在前面,避免新增路径覆盖掉之前定义的路径,减少潜在的冲突。

    系统查找命令时按照冒号分割顺序从前向后依次查找。

    配置路径的文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    sudo updatedb  # 更新数据库

    sudo gedit ~/.bashrc
    source ~/.bashrc
    sudo gedit ~/.zshrc
    source ~/.zshrc

    sudo gedit /etc/profile # 此文件涉及系统的环境,即环境变量相关。这里修改会对所有用户起作用。
    # 不能对zsh直接生效?需要在命令行里运行一遍source ~/.zshrc才能生效。
    source /etc/profile # 让环境变量生效

    sudo gedit /etc/ld.so.conf.d/opencv.conf
    sudo ldconfig # 运行配置

    sudo gedit /etc/ld.so.conf
    sudo ldconfig # 运行配置

    sudo gedit /etc/bash.bashrc
    source /etc/bash.bashrc
  2. Ubuntu快捷方式图标的存放位置:

    • /usr/share/applications
    • /usr/share/icons/Mojave-CT-Night/mimes/scalable
  3. 打开回收站:

    1
    cd ~/.local/share/Trash/files
  4. wine软件安装路径:/home/lll25655/.wine/drive_c/'Program Files (x86)'

  5. 打开eDiary:

    1
    wine /home/lll25655/.wine/drive_c/'Program Files (x86)'/eDiary-4.2.2-win64/eDiary.exe
  6. 第三方库库默认安装路径

    1. /usr/include

    2. /usr/local/include

  7. 字体安装路径:/usr/share/fonts

命令

软件、库的安装、卸载和升级

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 安装
sudo apt update # 先更新软件包列表,检查可用的软件包更新
# 查看可选的安装版本
apt-cache search exact_package_name # 你可以使用一个正则表达式来搜索本地 APT 缓存中的包。
apt-cache policy exact_package_name # 如果你指定了软件包的名称,它将显示该软件包是否已经安装,在哪个版本的仓库中可用,以及它的优先级。
sudo apt install exact_package_name[=xxx] # 安装软件,例如:sudo apt install libc6-dev=2.27-3ubuntu1.6

# 卸载(不知名的软件)
apt list --installed | grep -i possible_package_name # 模糊搜索
sudo apt remove exact_package_name # 卸载软件
sudo apt-get purge exact_package_name # 清除配置

# 升级
# apt 可以看作 apt-get 和 apt-cache 命令的子集, 可以为包管理提供必要的命令选项。apt-get 虽然没被弃用,但作为普通用户,还是应该首先使用 apt。
sudo apt update # 更新软件包列表,检查可用的软件包更新
apt list --upgradable # 查看可用安装
sudo apt upgrade # 安装可用的软件包更新
sudo apt install exact_package_name # 直接升级特定的包

优先级:

  • < 0:永远不会安装,
  • 1..99:仅当尚未安装其他版本的软件包时才会安装,
  • 100..499:仅当其他发行版中没有安装或提供其他更新版本时才会安装,
  • 500....989:仅当目标发行版中没有安装或没有更新的版本时才会安装,
  • 990..1000:将安装,除非安装的版本较新,
  • > 1000:将始终安装,即使它强制 APT 降级到旧版本。

默认情况下,每个已安装的软件包版本的优先级为 100,未安装的软件包的优先级为 500。同一软件包可能有多个不同优先级的版本。APT 会安装优先级较高的版本,除非安装的版本较新。

deb

安装路径

在 Ubuntu 下,使用 *.deb 包安装的软件,其主要文件会分散安装在系统的标准目录,而不是集中在某一个“专属”文件夹。具体来说:

  • 可执行文件(程序主文件)
    • 通常安装在 /usr/bin//usr/sbin//bin//sbin/ 等目录。
    • 例如:/usr/bin/vim/usr/bin/git
  • 配置文件
    • 一般安装在 /etc/ 目录下的子目录。
    • 例如:/etc/nginx//etc/mysql/
  • 库文件
    • 通常安装在 /usr/lib//usr/lib64/
    • 例如:/usr/lib/libreoffice/
  • 共享数据文件
    • 通常安装在 /usr/share/ 下。
    • 例如:/usr/share/doc/(文档)、/usr/share/applications/(桌面快捷方式)
  • 日志文件
    • 如果有日志,通常在 /var/log/ 下。
    • 例如:/var/log/nginx/
  • 卸载脚本、服务文件等
    • 可能会分布在 /etc/init.d//lib/systemd/system/ 等与服务相关的位置。
如何查看某个 .deb 包都装了哪些文件?
1
2
3
dpkg -L package_name
# 或者
dpkg-deb -c xxx.deb
卸载使用deb安装的软件

操作前确保备份重要数据,以防误删。

  1. 卸载软件包:

    1
    2
    3
    4
    # apt list --installed | grep -i possible_package_name  # 模糊搜索
    sudo apt remove package_name
    # or
    sudo dpkg -r package_name
  2. 彻底卸载并删除配置文件:

    1
    2
    3
    sudo apt purge package_name
    # or
    sudo dpkg --purge package_name
  3. (可选)自动清理无用依赖:

    1
    2
    sudo apt autoremove
    sudo apt autoclean

    该操作好像挺危险的,说不定会误删。

  4. 删除用户数据和用户信息:

    有的软件在用户目录下会有隐藏文件夹或配置(如 ~/.config/package_name~/.package_name 等),你可以手动删除这些目录

    1
    2
    3
    rm -rf ~/.config/package_name
    rm -rf ~/.package_name
    rm -rf ~/package_name

    如果软件为所有用户创建了专用的系统用户(比如 /home/someuser/var/lib/package_name),你还可以:

    1
    2
    sudo deluser someuser
    sudo rm -rf /home/someuser

    以及:

    1
    2
    sudo rm -rf /var/lib/package_name
    sudo rm -rf /etc/package_name

    软件在以上各文件夹内的命名不一定就是package_name,可能有大小写的区别,可能是缩写,等等。最好亲自去看看各文件夹内的内容来筛选和删除。

  5. 查找和删除残余文件:

    1
    sudo find / -name "*package_name*"

    删除搜索出的软件文件。

  6. 完成。

查找查看

辅助搭配

Linux grep (global regular expression) 命令用于查找文件里符合条件的字符串或正则表达式。

1
ls -l /usr/local | grep cuda  # 查询`/usr/local`路径下的软链接,且要求包括`cuda`字符串。

常用选项:

  • -i:忽略大小写进行匹配。
  • -v:反向查找,只打印不匹配的行。
  • -n:显示匹配行的行号。
  • -r:递归查找子目录中的文件。
  • -l:只打印匹配的文件名。
  • -c:只打印匹配的行数。

当前终端

1
2
3
4
5
6
7
8
9
10
cat /etc/shells  # 查看系统安装了的shell
# /usr/bin/zsh为软链接,指向/bin/zsh。可能是为了系统兼容性。
echo $SHELL # 当前的shell。实际没显示成功,但是确实改成功了?
# 切换终端Shell
chsh -s /bin/bash
chsh -s /bin/zsh
chsh -s $(which zsh)
# 或
exec bash # 将命令行从zsh切换为bash
exec zsh # 重新运行zsh命令行工具

环境变量

1
2
echo $PATH
echo $CUDA_HOME

内存

1
2
free -g  # 以 GB 为单位,显示内存使用情况。
# -s 根据指定的间隔时间,持续显示内存使用情况。

文件系统和挂载点

1
2
3
4
# 推荐,可查看到交换空间
cat /etc/fstab
# 或,信息更全,有硬盘使用率等
df -hT

文件(夹)大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看指定目录下的各文件(夹)大小
# du 命令需要在root权限下操作,或者在命令行前加sudo命令也可以。但排序是乱的,不好查看。
# 使用 sort 命令 的 -k 参数设置对第二列的值进行重排,也就是按照文件(夹)名进行排序
sudo du -ah --max-depth=1 --exclude=./proc --exclude=./tmp --exclude=./lost+found --exclude=./media --exclude=./mnt --exclude=./run /path/to/your/folder/ | sort -k 2

# 查看指定目录对应的磁盘空间大小
df -B G /path/to/your/folder/ # 以GB为单位显示指定磁盘文件的使用情况。如果没有指定文件,则显示所有挂载的文件系统的磁盘使用情况。
df -B M /path/to/your/folder/ # MB
# 加路径为当前路径所在的磁盘空间,不加路径为所有。

# 上述两个命令的常用参数:
-a或 -all 显示目录中个别文件的大小。
-h或 --human-readable 以K,M,G为单位,提高信息的可读性。
--max-depth=<目录层数> 超过指定层数的目录后,予以忽略。
-exclude=<目录或文件> 略过指定的目录或文件。

ll # 文件大小以字节为单位显示,并且在输出中的第 5 列。

文件(夹)修改时间

1
ll  # ls -l

文件(夹)权限

在使用 ls -l 命令时,第一列的其余 9 个字符表示文件或目录的访问权限,分别对应三个字符一组的 rwx 权限。例如:

  • r 表示读取权限
  • w 表示写入权限
  • x 表示执行权限
  • - 表示没有对应权限

前三个字符表示所有者的权限,中间三个字符表示所属组的权限,后三个字符表示其他用户的权限。

1
-rw-r--r-- 1 user group 4096 Feb 21 12:00 file.txt

表示文件名为file.txt的文件,所有者具有读写权限,所属组和其他用户只有读取权限。

版本信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# Linux内核版本
uname -a # 系统架构x64(x86_64、amd64)
# 系统架构:x64(x86_64、amd64)、arm64(aarch64)、mips64(mips64el)
# cmake
cmake --version
# conda
conda --version
# CPU核心数
nproc
# CPU占用
top
# CUDA
ls -l /usr/local | grep cuda # 检查是否安装了CUDA
nvcc -V # 查看自己安装的CUDA版本
lspci | grep -i nvidia # 检查系统是否有支持 CUDA 编程的 GPU
# cuDNN
apt show libcudnn8 # 通过查询已安装的libcudnn8包来验证cuDNN的版本
# 查看版本(路径可能不一致,有一个命令有输出就行)
cat /usr/include/cudnn_version.h
cat /usr/include/cudnn.h
cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2
# Eigen
/usr/include/eigen3 # Eigen安装路径
/usr/include/eigen330 # Eigen3.3.0安装路径
/usr/include/eigen340 # Eigen3.4.0安装路径
gedit /usr/include/eigen3/Eigen/src/Core/util/Macros.h
# GLIBC_
ldd --version
strings /lib/x86_64-linux-gnu/libm.so.6 |grep GLIBC_ # strings /lib64/libc.so.6 |grep GLIBC_
ll /lib/x86_64-linux-gnu/libm.so.6
# gcc
gcc -v
# java
java -version
# 内存
free
# NVIDIA
lspci | grep -i nvidia # 查看是否安装NVIDIA显卡
nvidia-smi # 查看显卡信息
watch -n 0.2 nvidia-smi # 每 0.2 秒刷新一次
# 显卡型号
lspci | grep -i nvidia
# Opencv
/usr/local # opencv3.1.0安装路径
/usr/local/opencv/opencv320 # opencv3.2.0安装路径
/usr/local/opencv/opencv345 # opencv3.4.5安装路径
pkg-config --modversion opencv # 查询版本
pkg-config --cflags opencv # 得到opencv的安装路径
# -> -I/usr/local/include/opencv -I/usr/local/include
pkg-config --cflags opencv4 # 附加:得到opencv4的安装路径
# openssl
openssl version -a
# Pangolin
find / -name pangolin
# protoc
protoc --version
# python
which python
ll /usr/bin/python
python -V # python --version
sudo update-alternatives --config python
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 2
# Qt5.9.9
qmake -v
# ROS
echo $ROS_PACKAGE_PATH

用户手册

Linux man 命令是 "manual" 单词的缩写,用于查看各种命令、函数和配置文件的手册页面。

1
man [选项] [节号] 命令/主题

查找文件

1
2
3
4
5
6
7
8
9
10
11
sudo updatedb  # 更新数据库

# find命令
find / -name httpd.conf # 在根目录下查找文件httpd.conf,表示在整个硬盘查找
find -name your-file-name # 在当前目录中搜索
# 可以使用通配符*来实现粗略匹配
# 可以逻辑运算符not(!)、and(-a)、or(-o) 一起使用以组成的复合条件进行文件查找
find / -name hello_world* 2>/dev/null # 忽略错误信息输出

# locate命令
locate filename

目录列表

1
2
3
4
5
6
7
8
pwd  # 显示当前目录位置 
ls
-a 显示所有文件及目录 ( 以. 开头的隐藏文件也会列出)
-l 以长格式显示文件和目录信息,包括权限、所有者、大小、创建时间等
-h:文件大小以K,M,G为单位,提高信息的可读性
ls /usr/bin/gcc* # 在/usr/bin目录下所有含有gcc前缀的文件
#此处使用 ll 命令更好(可以看到软链接):
ll /usr/bin/gcc*

文件内容

参考链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看整个文件
cat [filename] # cat /home/user/test.txt

# 查看开头几行
head -n [rows] [filename] # head -n 20 /home/user/test.txt

# 查看末尾几行
tail -n [rows] [filename] # tail -n 10 /home/user/test.txt

# 查看中间几行
# 方法一:
cat [filename]| head -n [endRow] | tail -n +[beginRow]
# 查看/home/user/test.txt的10~20行
# head -n 20 表示前20行
# tail -n 10 表示后10行
# tail -n +10 表示第10行之后的
cat /home/user/test.txt| head -n 20 | tail -n +10
# 方法二:
sed -n '[begin],[end]p' [filename]
sed -n '10,20p' /home/user/test.txt

查找过去编辑的文件

1
find . -type f -mmin -10  # 查找过去 10 分钟内编辑的所有文件

历史命令

1
2
3
4
history 5  # 这将显示您最近执行的五个命令,以便于快速调用和重新运行它们。
# 您可以使用感叹号 ( ! ) 后跟命令编号来快速重新执行历史记录中的任何命令。
# 例如,如果您想重新运行上面的mkdir newdir命令(命令号 125),您只需键入:
!125

文件新建、复制、移动、重命名和删除

基本

处理(特别是包含众多小文件的)大文件夹推荐使用[rsync](# rsync)命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
gedit ~/.bashrc	 # 使用gedit打开文件
touch file1.txt # 新建文件

mkdir [-p] dirName # 创建目录。-p 确保目录名称存在,不存在的就建一个。
mkdir -p runoob2/test # 在工作目录下的 runoob2 目录中,建立一个名为 test 的子目录。若 runoob2 目录原本不存在,则建立一个。(注:本例若不加 -p 参数,且原本 runoob2 目录不存在,则产生错误。)
mkdir -p {dev,test,prod}/{backend,frontend} # 使用大括号{}一次性创建多个目录

# 在指定的目录下,创建一个名为 LINK_NAME 的硬链接或符号链接,指向名为 TARGET 的文件或目录。
ln [OPTION]... [-T] TARGET LINK_NAME

# 复制文件或目录cp命令
# 示例
cp file.txt /path/to/destination/
-a:此选项通常在复制目录时使用,它保留链接、文件属性,并复制目录下的所有内容。其作用等于 dpR 参数组合。
-r 或 --recursive:用于复制目录及其所有的子目录和文件,如果要复制目录,需要使用该选项。
-i 或 --interactive:在复制前提示确认,如果目标文件已存在,则会询问是否覆盖,回答 y 时目标文件将被覆盖。
-p 或 --preserve:保留源文件的权限、所有者和时间戳信息。
在使用 cp 命令复制文件时,如果目标文件夹内存在同名文件,默认情况下,cp 命令会覆盖目标文件夹中的同名文件。
如果你希望在复制文件时避免覆盖同名文件,可以使用 -n 选项(即 --no-clobber),这样如果目标文件夹内存在同名文件,cp 命令将不会覆盖它们。
# 有斜杠,只复制内容;无斜杠,连目录一起复制。
cp -r /path/to/source_dir/ /path/to/destination/ # 把 source_dir 里面的所有文件和子目录直接复制到 destination/ 目录下
cp -r /path/to/source_dir /path/to/destination/ # 会把 source_dir 这个目录(连同它的内容)复制到 destination/ 目录下

# Linux `mv`(英文全拼:move file)命令用来为文件或目录改名、或将文件或目录移入其它位置
# 注意:需要先执行`Ctrl+H`显示隐藏文件命令,否则,隐藏文件以及隐藏文件夹不会被移动到新目录
# 将源文件名 source_file 改为目标文件名 dest_file
mv source_file(文件) dest_file(文件)
# 将文件 source_file 移动到目标目录 dest_directory 中
mv source_file(文件) dest_directory(目录)
# 目录名 dest_directory 已存在,将 source_directory 移动到目录名 dest_directory 中;
# 目录名 dest_directory 不存在则 source_directory 改名为目录名 dest_directory
mv source_directory(目录) dest_directory(目录)
# 出错
mv source_directory(目录) dest_file(文件)

# 删除文件和文件夹rm命令
rm -rf test/ # 删除 test 文件夹,删除文件夹要加 -r 参数。末尾的斜杠只是明确指示 test 是一个目录,但对于 rm 命令来说,这没有实际影响。
-i 删除前逐一询问确认。
-f 即使原档案属性设为唯读,亦直接删除,无需逐一确认。
-r 将目录及以下之档案亦逐一删除。
# 删除当前目录及其子目录中所有.json文件的bash命令:
find . -name "*.json" -type f -delete
# find:这是主命令,用于查找文件。
# .:这告诉find命令从当前目录开始搜索。
# -name "*.json":这告诉find命令查找所有以.json结尾的文件。
# -type f:这告诉find命令只查找文件,不包括目录。
# -delete:这告诉find命令删除找到的所有文件。

rsync

基本语法
1
sudo apt-get install rsync
  • -a, --archive: 归档模式,表示以递归的方式传输文件,并保持所有文件属性不变
  • --delete: 删除那些target中有而source没有的文件
  • --exclude: 指定排除不进行同步的文件,比如--exclude="*.iso"
  • -h: 以人类可读的格式输出。
  • --progress: 显示进度
  • -v: 详细输出模式
用法

rsync命令不仅可以传输文件夹,还可以传输单个文件。

复制/移动大文件夹

本机使用 rsync 命令时,可以作为cpmv命令的替代方法,将源目录同步到目标目录。

1
2
3
rsync -ahv --progress source/ destination/  # 把source文件夹的内容复制进destination文件夹
rsync -ahv --progress source destination/ # 把source文件夹复制进destination文件夹
rsync -ahv --progress source1/ source2/ destination/ # source1、source2都会被同步到destination目录。
删除大文件夹

在删除包含许多小文件的大文件夹时,可以考虑使用rsync命令,以提高删除速度。以下是具体步骤:

  1. 使用rsync将文件夹同步为空目录,达到快速删除文件的效果。
  2. 删除空目录。

具体命令如下:

1
2
3
4
mkdir empty_dir/  # 创建一个空目录
rsync -ahv --progress --delete empty_dir/ /path/to/your/folder/ # 将目标文件夹同步为空目录,快速删除文件内容
rmdir /path/to/your/folder/ # 删除同步后的空目录
rmdir empty_dir/ # 删除创建的空目录

请替换/path/to/your/folder/为你要删除的文件夹的实际路径。

增量备份

参考链接

rsync 的最大特点就是它可以完成增量备份,也就是默认只复制有变动的文件。

除了源目录与目标目录直接比较,rsync 还支持使用基准目录,即将源目录与基准目录之间变动的部分,同步到目标目录。

具体做法是,第一次同步是全量备份,所有文件在基准目录里面同步一份。以后每一次同步都是增量备份,只同步源目录与基准目录之间有变动的部分,将这部分保存在一个新的目标目录。这个新的目标目录之中,也是包含所有文件,但实际上,只有那些变动过的文件是存在于该目录,其他没有变动的文件都是指向基准目录文件的硬链接。

--link-dest参数用来指定同步时的基准目录。

1
rsync -a --delete --link-dest /compare/path /source/path /target/path

上面命令中,--link-dest参数指定基准目录/compare/path,然后源目录/source/path跟基准目录进行比较,找出变动的文件,将它们拷贝到目标目录/target/path。那些没变动的文件则会生成硬链接。这个命令的第一次备份时是全量备份,后面就都是增量备份了。

下面是一个脚本示例,备份用户的主目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash

# A script to perform incremental backups using rsync

set -o errexit
set -o nounset
set -o pipefail

readonly SOURCE_DIR="${HOME}"
readonly BACKUP_DIR="/mnt/data/backups"
readonly DATETIME="$(date '+%Y-%m-%d_%H:%M:%S')"
readonly BACKUP_PATH="${BACKUP_DIR}/${DATETIME}"
readonly LATEST_LINK="${BACKUP_DIR}/latest"

mkdir -p "${BACKUP_DIR}"

rsync -av --delete \
"${SOURCE_DIR}/" \
--link-dest "${LATEST_LINK}" \
--exclude=".cache" \
"${BACKUP_PATH}"

rm -rf "${LATEST_LINK}"
ln -s "${BACKUP_PATH}" "${LATEST_LINK}"

上面脚本中,每一次同步都会生成一个新目录${BACKUP_DIR}/${DATETIME},并将软链接${BACKUP_DIR}/latest指向这个目录。下一次备份时,就将${BACKUP_DIR}/latest作为基准目录,生成新的备份目录。最后,再将软链接${BACKUP_DIR}/latest指向新的备份目录。

复制时排除部分文件(夹)

示例:把某个文件夹(比如 /path/to/source)下的所有内容完整复制到一个新文件夹(比如 /path/to/target),但在复制过程中,排除掉所有叫 build 的文件夹(不管它们在什么层级)。

推荐方法:用 rsync
1
rsync -av --exclude='build/' /path/to/source/ /path/to/target/
  • --exclude='build/' :会排除所有名为 build 的目录(在任何层级都会被排除)。

    • --exclude=build:排除根目录下的 build 文件夹(只排除 source 根下的 build,不影响子目录里的 build)
  • /path/to/source/ 末尾的 / 表示复制“内容”,而不是把source文件夹本身也复制过去。

  • 这样,source下所有内容(除了任何层级的build文件夹)都会被复制到target

如果只能用 cp?

cp--exclude 选项并不支持递归排除所有层级的某个名字,需要结合 findcpio 或者 rsync。如果必须用纯 Bash,可以这样:

1
2
cd /path/to/source
find . -type d -name build -prune -o -print | cpio -pdm /path/to/target

如果只需要排除根目录下的build/

1
2
shopt -s extglob dotglob  # 开启扩展模式匹配,使得 shell 可以识别更多的模式匹配操作符
cp -r /path/to/source/!(build) /path/to/target/

mkcd

mkdircd命令合并为一个mkcd命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mkcd() {
mkdir -p "$1" && cd "$1"
}

# or
function mkcd {
if [ ! -n "$1" ]; then
echo "Enter mkcd followed by a directory name"
elif [ -d $1 ]; then
echo "\`$1' already exists"
else
mkdir $1 && cd $1
fi
}

这个函数接受一个参数($1),首先使用mkdir -p命令创建一个目录,然后使用cd命令进入这个目录。-p选项可以确保如果目录已经存在,mkdir命令不会报错。

你可以将这个函数添加到你的bash配置文件(如~/.bashrc~/.bash_profile)中,这样每次打开一个新的终端时,这个函数都会被定义。

使用这个函数的方式如下:

1
mkcd new_directory

这将创建一个名为new_directory的新目录,并立即进入这个目录。

下载

wget 与 curl 命令详解

测试网络连接:

1
ping www.baidu.com

wget

1
2
3
4
5
6
7
8
9
sudo apt install wget

# 下载单个文件
wget [options] <URL>
wget -O --show-progress myfile.zip http://www.example.com/testfile.zip # 如果不指定"-O" 选项,wget默认会以 url 路径最后一个 "/" 的后面全部字符为下载的文件名

# 断点续传
wget -c http://www.example.com/testfile.zip # 当下载的文件特别大或者网络原因,文件没有下载完连接就已经被断开,使用 -c 选项可以在网络连接恢复时接着上次的下载任务继续下载,而不需要重头开始下载文件
wget --tries=40 http://www.example.com/testfile.zip # wget默认重试20次连接下载文件,如果网络一直有问题下载可能失败。如果需要的话,你可以使用--tries增加重试次数。

下载超时,尝试添加参数--no-cookie --no-check-certificate

curl

1
2
3
4
5
6
7
8
9
10
11
# 单个文件下载
curl [ -o 自定义文件名| -O] --progress-bar http://www.example.com/index.html
# -o 自定义文件名:把服务器响应输出到指定文件
# -O:与-o选项作用一样,区别在于以 url 路径最后一个"/"之后的部分作为文件名
# 如果这两个选项都不写,curl 默认会把服务器响应内容输出到终端

# 断点续传
curl -O -C 偏移量 http://www.example.com/testfile.zip
# -C 偏移量:从指定的偏移量处继续下载,偏移量以字节为单位
# 如果让curl自动推断出正确的续传位置可以使用 "-" 代替偏移量,例如:
curl -O -C - http://www.example.com/testfile.zip

目录(跳转)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
mkdir 新建目录

./(点斜杠)表示当前工作目录的相对路径
.表示当前目录
..表示(当前目录的)父目录

pwd # 打印当前所在目录

cd dir # 切换到指定目录
cd / # 进入根目录
cd ~ # root用户, 相当于 cd /root;普通用户,相当于cd /home/当前用户名,即主目录
cd # 相当于 cd ~
cd - # 切换最开始的目录
cd . # 目前所在目录
cd .. # 返回上一层
cd ../.. # 返回上两层
cd ../*** # 进入当前目录父目录的**目录
cd ~=cd /root # 进入root的根目录

# 标记目录
# 记录当前目录路径,待会返回需要用到
cur=`pwd`
# 返回项目
cd $cur
  1. 把目录结构信息保存到文本中,树状图:

    1
    tree > /home/luke/tree.txt
  2. 在终端打开文件管理器:nautilusxdg-open[空格]目标路径。

    1
    2
    3
    4
    5
    nautilus /path/to/directory  # or
    xdg-open /path/to/directory
    # 打开当前终端所在目录
    nautilus . # or
    xdg-open .

压缩解压缩

zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 一般处理
zip -r FileName.zip DirName # 压缩
unzip test.zip # 解压
unzip -O GBK 6.zip # 解决解压出来中文乱码

# 高级处理
# 压缩、设置密码且分卷
zip -r -P 123456 temp.zip data/
zip -s 10m temp.zip --out data.zip
# 解压缩分卷
# 好用
sudo apt-get install p7zip
sudo apt-get install p7zip-full
sudo apt-get install p7zip-rar
7z x data.zip # 分卷文件在同一文件夹下,解压首文件即可,不需要合并分卷。密码会在解压终端提示输入。
# 不好用
cat data.* > tounzip.zip
unzip -P 123456 tounzip.zip

tar

.tar.gz = .tgz

1
2
tar -zcvf FileName.tar.gz DirName  # 压缩
tar -zxvf cmake-3.23.0-rc1.tar.gz # 解压
  • -z: 使用 gzip 压缩归档文件
  • -c: 创建新的归档文件
  • -x:解开压缩文件
  • -v: 显示详细输出,列出被添加到归档中的文件
  • -f: 指定归档文件的名称

tar.xz

1
2
3
4
5
6
7
8
# 压缩
tar -cvf Image.tar Image/
xz -z Image.tar # 如果要保留被压缩的文件加上参数 -k ,如果要设置压缩率加入参数 -0 到 -9 调节压缩率。如果不设置,默认压缩等级是6。

# 解压
# 先将Image.tar.xz 解压成 Image.tar
xz -d Image.tar.xz # 使用 -k 参数来保留被解压缩的文件。
tar -xvf Image.tar # 再用tar xvf Image.tar来解包

xz的参数:

  • -z, --compress: 强制压缩
  • -d, --decompress: 强制解压
  • -k, --keep: 保留(不删除)输入文件

pigz

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 压缩文件(夹)
tar --use-compress-program=pigz -cvpf /目录名/文件名.tgz (空格) /boot(压缩的文件或者目录)
--use-compress-program=pigz 是指定 ( pigz )来进行压缩
-cvpf
-c 创建压缩文件
-v 显示压缩或解压的过程
-p 保留原始的权限与属性
-f 目标文件名
--exclude=/xx 排除这个目录不压缩

# 解压文件(夹)
tar --use-compress-program=pigz -xvpf 文件.tgz -C / (这是指定解压到了根目录)(不加默认解压到当前文件夹)
--use-compress-program=pigz 是指定 ( pigz )来进行解压
-xvpf
-x 解开压缩文件
-v 显示压缩或解压的过程
-p 保留原始的权限与属性
-f 目标文件名
-C 指定解压到的目录

设置文件权限

chmod

指令名称:chmod

使用权限:所有使用者

使用方式:chmod [-cfvR] [--help] [--version] mode file...

参数格式:

  • u:表示该档案的拥有者。
  • g:表示与该档案的拥有者属于同一个群体(group)者。
  • o:表示其他以外的人。
  • a:表示这三者皆是。
  • +:表示增加权限。
  • -:表示取消权限。
  • =:表示唯一设定权限。
  • r:表示可读取。
  • w:表示可写入。
  • x:表示可执行。
  • X:表示只有当该档案是个子目录或者该档案已经被设定过为可执行。
  • R:对目前目录下的所有文件与子目录进行相同的权限变更(即以递归的方式逐个变更)
1
2
3
4
5
6
7
# 将档案 file1.txt 设为所有人皆可读取
chmod ugo+r file1.txt # 或
chmod a+r file1.txt
# 将档案 file1.txt 与 file2.txt 设为该档案拥有者,与其所属同一个群体者可写入,但其他以外的人则不可写入
chmod ug+w,o-w file1.txt file2.txt
# 将目前目录下的所有档案与子目录皆设为任何人可读取
chmod -R a+r *

此外chmod也可以用数字来表示权限,语法为:chmod abc file,其中a,b,c各为一个数字,分别表示User、Group、及Other的权限。

一般是三个数字:

  • 第一个数字表示文件所有者的权限。
  • 第二个数字表示与文件所有者同属一个用户组的其他用户的权限。
  • 第三个数字表示其它用户组的权限。

权限分为三种:读(r=4),写(w=2),执行(x=1)。综合起来还有可读可执行(rx=5=4+1)、可读可写(rw=6=4+2)、可读可写可执行(rwx=7=4+2+1)。

所以,chmod 755 设置用户的权限为:

  1. 文件所有者可读可写可执行
  2. 与文件所有者同属一个用户组的其他用户可读可执行
  3. 其它用户组可读可执行

777就是rwxrwxrwx,意思是该登录用户(可以用命令id查看)、他所在的组和其他人都有最高权限。

chmod 4755chmod 755 的区别在于开头多了一位,这个4表示其他用户执行文件时,具有与所有者相当的权限。具有root的权限。

chmod a=rwx filechmod 777 file效果相同。

chmod ug=rwx,o=x filechmod 771 file效果相同。

1
2
# 查看文件权限
ll

chown

用法

在 Linux/Unix 系统下,chown 命令用于更改文件或目录的拥有者(user)和所属组(group)。

1
chown [-cfhvR] [--help] [--version] user[:group] file...
  • user : 新的文件拥有者的使用者 ID
  • group : 新的文件拥有者的使用者组(group)
  • -c : 显示更改的部分的信息
  • -f : 忽略错误信息
  • -h :修复符号链接
  • -v : 显示详细的处理信息
  • -R : 处理指定目录以及其子目录下的所有文件
  • --help : 显示辅助说明
  • --version : 显示版本
1
sudo chown -R $(whoami):$(whoami) filepath
user和group的区别
  • user 指的是文件/目录的“所有者”(Owner),即一个具体的用户账号,比如 alicebobroot 等。
    • 拥有者对文件有独立权限(如读、写、执行)。
  • group 指的是文件/目录归属的“用户组”(Group),比如 staffwheelusersdevelopers 等。
    • 一个用户可以属于多个组,文件的 group 权限控制“同组成员”能否访问、修改文件。
1
2
3
chown bob file.txt # 只改拥有者:拥有者变为 bob,组不变
chown :wheel file.txt # 只改组:组变为 wheel,拥有者不变
chown bob:wheel file.txt # 同时改:拥有者变为 bob,组变为 wheel

chown和chmod的区别

命令 主要作用 控制内容 典型命令
chown 更改拥有者和用户组 user/group chown bob:staff file.txt
chmod 更改文件访问权限 r/w/x权限 chmod 755 file.txt
  • chown = 谁“拥有”这个文件/文件夹
    • chown 只是更改文件的拥有者(user)和用户组(group),并不会自动更改文件的读、写、执行权限设置。
    • 文件原有的权限(rwx)不会改变,只是“谁”享有这些权限的身份发生了变化。
  • chmod = “拥有者/组/其他人”各自拥有哪些读/写/执行权限

root用户把某个文件权限给到普通用户

1
2
3
4
5
6
7
8
9
10
# 先切换到root环境
su root
# 赋权
chown -R username filepath
# username 指的是 你的普通用户名称
# filepath 指的是 你需要赋权给普通用户的文件夹路径
# 这样普通用户也就可以操作这个路径下的文件了

# 示例:
sudo chown -R $(whoami):$(whoami) filepath

软/硬链接

区别

Linux ln 命令 - 菜鸟教程

  1. 硬链接
    • 对源文件创建硬链接,修改源文件,被硬链接的文件也会被修改;修改被硬链接的文件,源文件也会被修改。
    • 删除源文件,被硬链接的文件不受影响,因为硬链接和源文件指向相同的文件数据,只有当所有指向该数据的链接都被删除时,文件数据才会被删除。
    • 不允许给目录创建硬链接。
    • 硬链接只有在同一个文件系统中才能创建。(例如,电脑文件硬链接不到 U 盘)
  2. 软链接
    • 对源文件创建软链接,类似于对源文件创建快捷方式。
    • 删除源文件,软链接会失效,因为软链接只是指向源文件路径的引用。
    • 软链接可以对目录进行链接。
    • 软链接可以跨文件系统 ,硬链接不可以。

总结:

  • 硬链接:多个文件名指向同一个文件数据,删除其中一个文件名不会影响文件数据的存在。
  • 软链接:一个文件名指向另一个文件名,删除源文件会导致软链接失效。

创建

1
ln [参数][源文件或目录][目标文件或目录]
  • -s: 软链接(符号链接)
  • -v: 显示详细的处理过程
1
2
3
4
# 给文件创建软链接,为log2013.log文件创建软链接link2013.log,如果log2013.log丢失,link2013.log将失效:
ln -s log2013.log link2013.log
# 给文件创建硬链接,为log2013.log创建硬链接ln2013.log,log2013.log与ln2013.log的各项属性相同
ln log2013.log ln2013.log

如果为源文件创建的目标(硬)链接是文件夹,则会在该文件夹下创建于源文件同名的文件。

你可以使用 find 命令结合 ln 命令来为指定目录下的所有文件在另一个目录下创建硬链接。以下是一个示例脚本,假设你要为 source_dir 目录下的所有文件在 target_dir 目录下创建硬链接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

source_dir="/path/to/source_dir"
target_dir="/path/to/target_dir"

# 创建目标目录(如果不存在)
mkdir -p "${target_dir}"

# 遍历 source_dir 目录下的所有文件,并在 target_dir 目录下创建硬链接
find "${source_dir}" -type f | while read -r file; do
# 获取相对路径
relative_path="${file#${source_dir}/}"
# 创建硬链接的目标路径
target_file="${target_dir}/${relative_path}"
# 创建目标文件所在的目录(如果不存在)
mkdir -p "$(dirname "${target_file}")"
# 创建硬链接
ln "${file}" "${target_file}"
done

以下是如何在Python中创建硬链接和软链接的示例代码:

创建硬链接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import os

def create_hard_link(src_file, dest_file):
try:
os.link(src_file, dest_file)
print(f"硬链接已创建:{src_file} -> {dest_file}")
except FileExistsError:
print(f"目标文件已存在:{dest_file}")
except OSError as e:
print(f"创建硬链接失败:{e}")

src_file = "path/to/your/file.txt"
dest_file = "path/to/backup/folder/file.txt"
create_hard_link(src_file, dest_file)

创建软链接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import os

def create_soft_link(src_file, dest_file):
try:
os.symlink(src_file, dest_file)
print(f"软链接已创建:{src_file} -> {dest_file}")
except FileExistsError:
print(f"目标文件已存在:{dest_file}")
except OSError as e:
print(f"创建软链接失败:{e}")

src_file = "path/to/your/file.txt"
dest_file = "path/to/backup/folder/file.txt"
create_soft_link(src_file, dest_file)

查看

  • 软链接:

    1
    ll
  • 硬链接。在Linux终端中,可以使用ls命令配合-i选项来查看文件的inode号,从而识别硬链接。所有具有相同inode号的文件都是同一个文件的硬链接。以下是具体步骤:

    1
    2
    3
    4
    5
    # 使用ls -i命令查看文件的inode号:
    ls -i file1
    # 使用find命令查找具有相同inode号的所有文件:
    find . -inum <inode_number> # . 表示载当前目录及其子目录下进行查找,可以换成其它指定目录。
    # 这样,你就可以看到所有指向同一个inode的硬链接文件。

硬盘

挂载硬盘

1
2
3
4
5
# 挂载 U 盘根目录的内容会直接出现在 /mnt/ 文件夹内,
# 而不是 /mnt/ 文件夹内先有一个U盘的名称,名称文件夹内再有内容。
# 因此,如有需要,需要提前在 /mnt/ 下使用 sudo 新建文件夹。
sudo mount /dev/sdX1 /mnt/ # mount part
sudo umount /mnt/ # 卸载

其中,/dev/sdX1是U盘的设备名,你可以使用lsblkfdisk -l命令来查找U盘的设备名。

例如,插入硬盘前后,使用lsblk发现新增:

1
2
sdc      8:32   0   7.3T  0 disk 
└─sdc1 8:33 0 7.3T 0 part

硬盘类型

在Linux系统上,可以使用以下命令来查看硬盘是机械硬盘(HDD)还是固态硬盘(SSD):

1
cat /sys/block/sdX/queue/rotational

sdX替换为硬盘的设备名,比如sda。如果输出是1,则表示是机械硬盘;如果输出是0,则表示是固态硬盘。

除了查看/sys/block目录下的信息外,你还可以使用lsblk命令结合-o选项来获取更多详细信息,包括硬盘类型:

1
lsblk -d -o name,rota
  • lsblk 列出所有块设备。
  • -d 选项只显示磁盘本身,不显示其分区。
  • -o 选项指定要显示的列,其中name表示设备名,rota表示是否是旋转设备(0表示固态硬盘,1表示机械硬盘)。

通过这种方式,你可以在一个命令中看到所有硬盘的类型。

模拟鼠标键盘

https://github.com/jordansissel/xdotool

作用:xdotool允许您以编程方式(或手动)模拟键盘输入和鼠标活动、移动窗口和调整窗口大小等。

用户文档:https://github.com/jordansissel/xdotool/blob/master/xdotool.pod

Linux之xdotool工具安装及实践

安装

  • Debian and Ubuntu: apt-get install xdotool
  • Fedora: dnf install xdotool
  • FreeBSD: pkg install xdotool
  • macOS: brew install xdotool or sudo port install xdotool
  • OpenSUSE: zypper install xdotool

使用

xdotool 支持在一次调用中运行多个命令。

在 GNOME 终端中使用xdotool key Ctrl+c是成功的,使用xdotool key Ctrl+C是失败的(xdotool key ctrl+c在 ROS 下失败),关键在于字母c要小写。在 Terminator 窗口下没有此现象。因此,干脆没有特殊要求就直接用小写吧。

帮助
1
xdotool help
键盘
1
2
3
4
5
6
7
8
9
# 发送按键
xdotool key [options] keystroke [keystroke ...]
[options]
--window window # 将击键发送到特定窗口 ID
--clearmodifiers # 在发送击键之前清除修饰符
--delay milliseconds # 按键之间的延迟。默认值为 12 毫秒

# 示例
xdotool key Ctrl+Shift+W BackSpace

模拟打字并按回车键:

1
2
xdotool type "s
"
1
2
3
4
5
6
# 发送按下/释放按键的事件
xdotool keydown/keyup [options] keystroke
* keydown # [options] 与 key 相同,只是仅发送 keydown(按下)事件。
* keyup # [options] 与 key 相同,只是仅发送 keyup(释放)事件。
# 示例
xdotool keydown n
1
2
3
4
# 发送字符串
xdotool type [options] something to type # [options] 与 key 相同
# 示例
xdotool type 'Hello world!'
鼠标
1
2
3
4
5
6
7
8
9
10
11
12
13
# 将鼠标移动到屏幕上的特定 X 和 Y 坐标。
xdotool mousemove [options] x y OR 'restore'

# 如果指定“restore”而不是 X 和 Y 坐标,则可以将鼠标移动到之前的位置。仅当您之前在同一命令调用中进行过移动时,restore 才有效。此外,它不适用于 --window 选项。
# 示例
xdotool mousemove 0 0 click 1 mousemove restore # 单击屏幕左上角并将鼠标移动到移动之前的原始位置

[options]
--window WINDOW # 指定要相对移动的窗口。坐标 0,0 位于您选择的窗口的左上角。
--screen SCREEN # 将鼠标移动到要移动到的指定屏幕。仅当您有多个屏幕并且不使用 Xinerama 时,这才有用。默认为当前屏幕。如果指定 --window,则忽略 --screen 标志。
--polar # 使用极坐标。这使得“x”成为角度(以度为单位,0-360 等),“y”成为距离。旋转从“向上”(0 度)开始并顺时针旋转:90 = 向右,180 = 向下,270 = 向左。原点默认为当前屏幕的中心。如果指定 --window,则原点是该窗口的中心。
--clearmodifiers # 清除修饰符
--sync # 发送鼠标移动请求后,等待鼠标实际移动。如果没有必要采取行动,我们就不会等待。这对于依赖于在继续之前完成的操作的脚本非常有用。
1
2
# 相对于鼠标光标的当前位置移动鼠标 x,y 像素。
xdotool mousemove_relative [options] x y # [options] 与 mousemove 相同
1
2
3
4
5
6
7
8
9
# 模拟单击
xdotool click [options] button
# 按钮通常这样映射:鼠标左键为 1,中键为 2,右键为 3,向上滚轮为 4,向下滚轮为 5。

[options]
--clearmodifiers # 单击之前清除修饰符
--repeat REPEAT # 指定单击次数。默认值为 1。对于双击,请使用“--repeat 2”
--delay MILLISECONDS # 指定单击之间的延迟时间(以毫秒为单位)。如果--repeat标志设置为 1(默认),则不使用此选项。
--window WINDOW # 指定要向其发送点击的窗口。
1
2
# 与 click 相同,但仅发送鼠标按下/松开操作。
xdotool mousedown/mouseup [options] button
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 输出鼠标光标的 x、y、屏幕和窗口 ID。如果您有多个显示器并且不使用 Xinerama,则屏幕编号将非零。
xdotool getmouselocation [--shell]
--shell # 这使得 getmouselocation 输出可以 eval 的 shell 数据。

# 示例
% xdotool getmouselocation --shell
X=880
Y=443
SCREEN=0
WINDOW=16777250

% eval $(xdotool getmouselocation --shell)
% echo $X,$Y
714,324
1
2
3
# 当鼠标点击屏幕边缘或角落时,将操作绑定到事件。
xdotool behave_screen_edge [options] where command ...
# 略
窗口
1
2
3
# 搜索具有正则表达式模式的标题、名称或类的窗口。
xdotool search [options] pattern
# 略
1
2
3
# 通过单击获取窗口 ID(针对客户端)。对于让脚本向您询问要在哪个窗口上执行操作非常有用。
# 例如,通过单击来杀死一个窗口:
xdotool selectwindow windowkill
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 将操作绑定到窗口上的事件。这使您可以在发生匹配事件时运行其他 xdotool 命令。
xdotool behave window action command ...
* mouse-enter # 当鼠标进入窗口时触发。
* mouse-leave # 当鼠标离开窗口时触发。
* mouse-click # 单击鼠标时触发。具体来说,当释放鼠标按钮时。
* focus # 当窗口获得输入焦点时触发。
* blur # 当窗口失去焦点时触发。

# 示例
# Print the cursor location whenever the mouse enters a currently-visible
# window:
xdotool search --onlyvisible . behave %@ mouse-enter getmouselocation

# Print the window title and pid whenever an xterm gets focus
xdotool search --class xterm behave %@ focus getwindowname getwindowpid

# Emulate focus-follows-mouse
xdotool search . behave %@ mouse-enter windowfocus
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 输出当前活动窗口。该命令通常比 getwindowfocus 更可靠。结果保存到窗口堆栈中。
xdotool getactivewindow

# 打印当前焦点窗口的窗口 ID。将结果保存到窗口堆栈。
xdotool getwindowfocus [-f]
# 如果当前窗口没有 WM_CLASS 属性,我们假设它不是一个普通的顶级窗口,并向上遍历父窗口,直到找到一个设置了 WM_CLASS 的窗口并返回该窗口 id。
# 如果您确实希望当前窗口具有焦点并且不关心它是否具有 WM_CLASS 设置,请使用“getwindowfocus -f”

# 激活窗口。
# 该命令与 windowfocus 不同:如果窗口位于另一个桌面上,我们将切换到该桌面。它还使用不同的方法来打开窗口。
xdotool windowactivate [options] [window]

# 输出拥有给定窗口的 PID。
xdotool getwindowpid [window]
# 如果未给出窗口,则默认值为“%1”。如果堆栈上没有窗口,则这是一个错误。

# 输出给定窗口的名称,也称为标题。这是窗口管理器在窗口标题栏中显示的文本。
xdotool getwindowname [window]
# 如果未给出窗口,则默认值为“%1”。如果堆栈上没有窗口,则这是一个错误。

# 输出窗口的几何形状(位置和位置)。这些值包括:x、y、宽度、高度和屏幕编号。
xdotool getwindowgeometry [options] [window]
--shell # 适合 shell 中“eval”的输出值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 关闭一个窗口。此操作将破坏窗口,但不会尝试杀死控制它的客户端。
xdotool windowclose [window]

# 优雅地关上窗户。此操作发送请求,允许应用程序应用关闭确认机制。
xdotool windowquit [window]

# 杀死一扇窗户。此操作将破坏窗口并杀死控制它的客户端。
xdotool windowkill [window]

# 设置有关窗口的属性。
xdotool set_window [options] [windowid=%1]
# 略

# 更改窗口的属性。
windowstate [--add PROPERTY] [--remove PROPERTY] [--toggle PROPERTY] [window]
# 略

# 设置给定窗口的窗口大小
xdotool windowsize [options] [window] width height
# 略

# 将窗口移动到给定位置
xdotool windowmove [options] [window] x y
# 略

# 聚焦一个窗口
xdotool windowfocus [options] [window]
--sync # 发送窗口焦点请求后,等待窗口真正获得焦点。这对于依赖于在继续之前完成的操作的脚本非常有用。

# 映射一个窗口。在 X11 术语中,映射窗口意味着使其在屏幕上可见。
xdotool windowmap [options] [window]
# 略

# 取消映射窗口,使其不再出现在屏幕上。
xdotool windowunmap [options] [window_id=%1]
# 略

# 最小化一个窗口。
xdotool windowminimize [options] [window]
# 略

# 将窗口提升到堆栈顶部。
xdotool windowraise [window_id=%1]
# 略

# 将窗口降低到堆栈底部。
xdotool windowlower [window_id=%1]
# 略

# 重新设置窗口的父级。
xdotool windowreparent [source_window] destination_window
# 略

sleep

Linux sleep命令可以用来将目前动作延迟一段时间。

1
sleep [--help] [--version] number[smhd]
  • --help : 显示辅助讯息
  • --version : 显示版本编号
  • number : 时间长度,后面可接 s、m、h 或 d。其中 s 为秒,m 为 分钟,h 为小时,d 为日数
1
sleep 5m  # 休眠5分钟

后台运行

有时,您需要执行一个即使在您注销终端会话后也会继续运行的命令。nohup(无挂起)命令允许您在后台运行进程而不会中断。例如,使用nohup long_running_command &在后台启动命令,即使在关闭终端后也能保持其运行。此功能对于执行需要在没有持续监督的情况下持续存在的冗长任务或脚本特别有价值。

并行运行

1
2
command1 & command2 & command3
parallel ::: command1 command2 command3

定时关机

https://www.runoob.com/linux/linux-comm-shutdown.html

1
shutdown [-t seconds] [-rkhncfF] time [message]

参数说明

  • -t seconds : 设定在几秒钟之后进行关机程序。
  • -k : 并不会真的关机,只是将警告讯息传送给所有使用者。
  • -r : 关机后重新开机。
  • -h : 关机后停机。
  • -n : 不采用正常程序来关机,用强迫的方式杀掉所有执行中的程序后自行关机。
  • -c : 取消目前已经进行中的关机动作。
  • -f : 关机时,不做 fsck 动作(检查 Linux 档系统)。
  • -F : 关机时,强迫进行 fsck 动作。
  • time : 设定关机的时间。
  • message : 传送给所有使用者的警告讯息。
1
2
3
4
sudo shutdown -h now  # 立即关机
sudo shutdown -h 10 # 指定 10 分钟后关机
sudo shutdown -r now # 重新启动计算机
sudo shutdown -c # 取消定时关机
1
2
sudo apt-get install at
echo "sudo shutdown -h now" | at 23:00 # 在晚上 11 点关机

Shebang

在Linux或Unix系统中,Shebang(亦称为释伴)是一个由井号(#)和叹号(!)组成的字符序列,通常位于脚本文件的第一行。Shebang指明了执行该脚本文件的解释器路径,使得脚本可以像普通的可执行文件一样被调用。

shebang(如 #!/usr/bin/zsh 只有在你直接执行脚本(如 ./test.sh)时才决定用哪个解释器。当你用bash test.sh运行时,系统会:

  1. 启动你命令里写明的 bash
  2. bash 再去读取 test.sh 的内容并执行,不会理会 shebang

所以,无论 test.sh 开头写什么 shebang,bash test.sh 都是用 bash 解释运行。

特性 ./test.py python test.py
依赖 shebang 是,shebang 必须正确指定解释器 否,解释器由用户显式调用
文件可执行权限 需要(chmod +x test.py 不需要
解释器版本选择的灵活性 固定,由 shebang 指定 用户可以自由选择解释器
适用场景 脚本自动化、作为独立命令运行 开发和调试脚本,或需要指定特定解释器版本

小贴士

Linux顺序执行多行命令

  • 分号;
    • 没有任何逻辑关系的连接符。当多个命令用分号连接时,各命令之间的执行成功与否彼此没有任何影响,都会一条一条执行下去。
  • 逻辑或||
    • 当用此连接符连接多个命令时,前面的命令执行成功,则后面的命令不会执行。前面的命令执行失败,后面的命令才会执行。
  • 逻辑与&&
    • 当用此连接符连接多个命令时,前面的命令执行成功,才会执行后面的命令,前面的命令执行失败,后面的命令不会执行,与 || 正好相反。
  • 管道符|
    • 当用此连接符连接多个命令时,前面命令执行的正确输出,会交给后面的命令继续处理。若前面的命令执行失败,则会报错,若后面的命令无法处理前面命令的输出,也会报错。

在Linux中使用AppImage

  1. 使其可执行。右键-属性-权限-允许将文件作为程序执行;或,命令行执行:

    1
    2
    3
    4
    chmod u+x <AppImage File>
    # u user 文件所有者
    # + 为指定的用户类型增加权限
    # x 执行权限 设置为可执行权限
  2. 运行 AppImage 文件。使 AppImage 文件可执行后,只需双击它即可运行它。它将看到该软件正在运行,就像您在系统上安装它一样;或,命令行执行:

    1
    ./app.appimage  # sudo
  3. 卸载 AppImage 软件。由于从未安装过该软件,因此无需“卸载”它。只需删除关联的 AppImage 文件,您的软件就会从系统中删除。

其它

  1. Linux diff 命令用于比较文件的差异。diff 以逐行的方式,比较文本文件的异同处。如果指定要比较目录,则 diff 会比较目录中相同文件名的文件,但不会比较其中子目录。

  2. 指令需要root权限,要么命令前加sudo进行提权,要么以root身份执行。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # Ubuntu 首次进入 root 用户模式
    # 开启一个新的终端

    # 设置 root 用户密码(Linux下输入的密码默认不会显示出来)
    sudo passwd root
    # 输入一个新的密码: yourpassword
    # 请在确认一遍密码: yourpassword

    # 切换到root用户
    su root
    # 输入刚刚设置的密码

    # 退出root用户
    exit
  3. $表示普通用户,#表示root用户。

  4. 定义环境变量:

    1
    2
    sudo gedit ~/.bashrc
    export OPENAI_API_KEY={Your OpenAI API Key here}
  5. timeout是用来控制程序运行的时间,运行指定的命令。如果在指定时间后仍在运行,则杀死该进程。

    1
    2
    3
    4
    5
    timeout 5s ping www.baidu.com  # 5分钟之后终止ping操作
    s : 秒 (默认)
    m : 分钟
    h : 小时
    d : 天
  6. 等等。

小贴士

  1. 直接在当前文件夹窗口打字,可以搜索该目录及子目录下的文件(夹)。按ESC键退出。
  2. Application 键即位置在键盘上右 Ctrl 键左边的那个键,作用相当于单击鼠标右键。
  3. 误按Ctrl+Alt+F7(进入文字界面)黑屏后按Ctrl+Alt+F1回到图形界面。
  4. 直接将"文件管理器"中的文件拖到"终端"中就可以在终端中得到完整的路径名。

终端Terminal

命令行解释器Shell

终端负责是从用户这里接收输入(键盘、鼠标等输入设备),扔给 Shell,然后把 Shell 返回的结果展示给用户(比如通过显示器)。而 Shell 负责从终端那里拿到用户输入的命令,解析后交给操作系统内核去执行,并把执行结果返回给终端。

Bash

快捷键 作用
Tab zsh自动补全
Ctrl+C 终止进程/命令
Ctrl+V 插入特殊字符。当你按下Ctrl+V后,终端会等待你输入下一个字符,然后将其ASCII值插入到当前位置。例如,如果你按下Ctrl+V然后按Enter,终端将插入一个表示换行的特殊字符。
Shift+Ctrl+C 复制
Shift+Ctrl+V 粘贴
Shift+Ctrl+F 查找
Shift+Ctrl+T 新建标签页
Shift+Ctrl+N 新建同路径窗口
Shift+Ctrl+W 关闭标签页
Shift+Ctrl+Q 关闭窗口
Ctrl+A 光标移动到开始位置
Ctrl+E 光标移动到最末尾
Ctrl+K 删除此处至末尾的所有内容
Ctrl+U 删除此处至开始的所有内容
Ctrl+W 当在控制台或一个xterm窗口敲入文本时, CTRL+W 会删除从在光标处往后(回)的第一个空白符之间的内容。在某些设置里, CTRL+W 删除光标往后(回)到第一个非文字和数字之间的字符。
Ctrl+L 类似于clear,即清屏。其实只是把光标位置移动到屏幕顶部,仍保留了之前的终端内容。
Ctrl+Y 将之前已经清除的文本粘贴回来(主要针对CTRL+U或CTRL+W)。
Ctrl+S 冻结终端
Ctrl+Q 解冻终端
Ctrl+T 将光标位置的字符和前一个字符进行位置交换
Ctrl+R 以交互方式搜索命令历史记录
Ctrl+PGUP/PGDN 切换到上/下一个标签页
Ctrl+Shift+↑/↓ 向上/下滚动内容
Shift+PageUp/PageDown 向上/下翻页

Terminator

更方便的终端,区别于默认GNOME终端。

快捷键 作用
Ctrl+Shift+E 垂直分割窗口
Ctrl+Shift+O 水平分割窗口
F11 全屏
Ctrl+Shift+C 复制
Ctrl+Shift+V 粘贴
Shift+Ctrl+W 关闭(当前)终端
Shift+Ctrl+Q 关闭窗口
Ctrl+Shift+N/Ctrl+Tab 在分割的各窗口之间切换
Alt+Up/Down/Left/Right 移动到上/下/左/右边的终端
Ctrl+Shift+Up/Down/Left/Right 在水平/垂直分割的终端中将分割条向上/下/左/右移动
Ctrl+Shift+X 将分割的某一个窗口放大至全屏使用
Ctrl+Shift+Z 从放大至全屏的某一窗口回到多窗格界面

选中即复制,鼠标中键粘贴。对于单词,双击即可选中,三击选中一行。

tips

终端程序静默运行

  • 在 Linux(以及类 Unix 系统)的终端(shell)中,命令末尾加上 &,表示让该命令在“后台”运行。这就是常说的“后台进程”(background process)。
  • 默认情况下,你在终端执行一个命令,shell 会等待该命令执行完毕,期间终端会被该进程“占用”。
  • 加上 &,shell 会让这个命令在后台运行,立即把控制权还给你,你可以继续在终端输入其它命令,甚至直接关闭终端窗口(如果进程没有依赖终端,则不会被终端关闭而退出)。
  • 图形界面(GUI)程序(如 VS Code)通常加 & 就足够,不会因为关闭终端而退出(但在某些特殊终端或远程 SSH 下还是建议用 nohup)。

Shell脚本一次性启动多个程序(对应多个终端)

经常开发ros环境的应该知道,当节点太多难以控制的时候,不如写个脚本直接启动多个节点(对应多个终端)。

先介绍一下gnome-terminal命令的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
gnome-terminal  # 打开一个新的终端
# 参数
# 基本用法
--maximize # 打开后自动最大化
--full-screen # 打开后全屏
--window # 打开多个终端,多个标签页
gnome-terminal --window --window #打开两个
gnome-terminal --window --tab --window --tab --tab #打开两个,第一个两个tab,第二个3个tab
-t # 设置终端的标题。注意,有些版本不支持。
# 设置打开的位置和大小(宽度x高度+左侧偏移量+上方偏移量)
gnome-terminal --geometry=80x25+10+10

# 启动后自动执行命令
-e # 可以出现多次。如果在所有--window前面,表示对所有window和tab起作用,如果在--window或者--tab后面,表示只针对这个tab执行,要注意-e后面只能有一个参数,也就是说如果有空格,需要用引号。
-x # 只能出现一次,在-x后面的所有内容,均认为是要执行的命令,所以可以出现空格,这些命令是针对所有tab都执行的。
gnome-terminal -x bash -c "ls"
gnome-terminal -e 'bash -c "ls"'
# 注,运行时会警告:
# 参数“-x”弃用并可能在 gnome-terminal 的后续版本中移除。
# 参数“-e”弃用并可能在 gnome-terminal 的后续版本中移除
# 使用“-- ”以结束选项并将要执行的命令行追加至其后。
# 所以,现在可以直接用“--”来替换掉“-x”和“-e”了。

# 执行完成后保持终端不自动关闭。
# 1. 最后加上exec bash的命令,并用分号跟前面的命令隔开。
gnome-terminal -x bash -c "ls; exec bash"
gnome-terminal -e 'bash -c "ls; exec bash"'
# 2. 修改terminal的配置,在terminal点右键,选择Profiles->Profile Preferences,然后找到Title and Command,里面有一项When command exits,后面选择为Hold the terminal open,然后就可以了。
# 3. 把结果重定向给less,这样less执行完之前,是不会退出的。
gnome-terminal -x ls|less

了解上面后我们可以创建属于自己的脚本了:

  1. 在ROS工作空间(例如,catkin_ws文件夹)下创建一个脚本文件,例如runROS.sh

  2. 写入内容,例如:

    1
    2
    3
    4
    5
    6
    #!/bin/bash
    gnome-terminal --window -- bash -c "source ./devel/setup.bash && roslaunch PACKAGE_NAME *.launch; exec bash"
    sleep 3s
    gnome-terminal --window -- bash -c "source ./devel/setup.bash && rosrun PACKAGE_NAME NODE_NAME *.yaml; exec bash"
    sleep 3s
    gnome-terminal --window -- bash -c "rosbag play /yourfolder/*.bag; exec bash"

    需要什么节点按照这个模块添加即可。

    对于使用Terminator终端和zsh shell,修改文件内容为:

    1
    2
    3
    4
    5
    6
    #!/bin/zsh
    terminator -e "zsh -c 'source ./devel/setup.zsh && roslaunch PACKAGE_NAME *.launch; exec zsh'"
    sleep 3s
    terminator -e "zsh -c 'source ./devel/setup.zsh && rosrun PACKAGE_NAME NODE_NAME *.yaml; exec zsh'"
    sleep 3s
    terminator -e "zsh -c 'source ./devel/setup.zsh && rosbag play /yourfolder/*.bag; exec zsh'"

    这里播放rosbag前面需要加上source ./devel/setup.zsh,否则会报错zsh:1: command not found: rosbag

    如果exec zsh命令未能在命令运行完成后保持终端窗口打开,可以尝试修改terminal的配置,在terminal点右键,选择Profiles->Profile Preferences,然后找到Title and Command,里面有一项When command exits,后面选择为Hold the terminal open。

    因为roscoreroslanuch打开ROS节点后不会自行关闭,需要使用快捷键Ctrl+C手动关闭,所以不会运行到exec zsh这一步。

    而且,使用快捷键Ctrl+C手动关闭ROS节点后,终端会直接退出,也就是关闭窗口(这个BUG?反而能自动关闭终端窗口,减少了自己的操作?)。

    如果Ctrl+C后不想关闭终端,可以在terminal点右键,选择Profiles->Profile Preferences,然后找到Title and Command,里面有一项When command exits,后面选择为Hold the terminal open。不过即使这样,当前终端也不再能输入命令,只能使用Terminator的功能水平分割/数值分割另起一个终端。

    当我手动 Ctrl + C 关闭 gnome-terminal + zsh,时,程序完全退出后才会关闭终端窗口。但当我使用 xdotool 模拟 Ctrl + C时,就算保持窗口常开,程序也会直接退出(留下一个临时文件),而不像手动时会处理完临时文件后再退出。相反,当我使用 gnome-terminal + bash 时,程序总会完全退出并保持窗口。这在有些情况下反而是可取的。

  3. 给脚本文件授予权限:

    1
    sudo chmod 755 runROS.sh

    chmod 755 设置用户的权限为:

    1. 文件所有者可读可写可执行。
    2. 与文件所有者同属一个用户组的其他用户可读可执行。
    3. 其它用户组可读可执行。
  4. 运行脚本文件:

    1
    2
    cd catkin_ws
    ./runROS.sh
  5. 完成。

进阶使用

Shell脚本在语句报错后终止运行

set命令

  • set -e:启用错误检测,命令返回非零状态时脚本立即退出。

    set -e命令的作用域是全局的,也就是说,一旦执行了set -e命令,它会影响整个脚本中所有后续的命令,无论它是在if语句内还是外面。

  • set +e:禁用错误检测,命令返回非零状态时脚本继续执行。

  • set -x:启用调试模式,执行命令前打印命令。

  • set +x:禁用调试模式,执行命令前不打印命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash

# 启用错误检测
set -e

# 一个成功的命令
echo "This command will succeed."
ls /

# 禁用错误检测,以便处理单个命令的错误
set +e

# 一个可能失败的命令
echo "This command may fail."
ls /nonexistent_directory
status=$?

# 手动检查命令的退出状态
if [ $status -ne 0 ]; then
echo "The command failed with status $status. Handling the error..."
# 在此处添加错误处理逻辑
else
echo "The command succeeded."
fi

# 重新启用错误检测
set -e

# 另一个成功的命令
echo "This command will also succeed."
ls /

echo "Script completed."

继续执行

shell脚本在语句报错后默认仍会继续向下执行,解决方法为:

1
2
3
4
5
6
7
8
#!/bin/bash
# 增加语句
set -e
# 或,二选一即可
set -o errexit
# 或,使用逻辑与
python3 main.py &&
python3 do.py

Shell脚本自动输入密码

1
echo "password" | sudo -S command  # 可见加上-S参数sudo才会从标准输入中读取密码,不加-S参数以上命令将起不到作用

Shell脚本按下Ctrl+C后仍可以执行功能

How to handle ctrl+c in bash scripts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash

cleanup(){
echo ""
echo "CTRL+C pressed, clean up things before exiting..."
rm -rf test.tmp 2>/dev/null
exit 1
}

# Trap the SIGINT signal (Ctrl+C)
trap cleanup SIGINT

while true; do
touch test.tmp
sleep 1
echo "Running..."
rm -f test.tmp
done

trap命令允许捕获信号(Ctrl+C是SIGINT信号)并在捕获后执行命令,trap语法如下:

1
trap function_command_to_execute SIGNAL
  • 为什么你使用 echo 两次?
    • 按 ctrl+c 而不输入换行符会弄乱输出。
  • 为什么将 stderr 重定向到/dev/null
    • /dev/null是一个特殊的设备名称,充当黑洞!你扔在那里的所有东西都会消失!这样,如果我们尝试删除的文件已经被删除,则屏幕上不会显示错误,这可能会无缘无故地让用户感到困惑!
  • 为什么用 exit 1 退出脚本?
    • 退出代码非常有用!退出代码 0 表示程序/脚本按预期完成,其他任何值都可能表示因异常方式或错误退出。
    • 这使得故障排除更加容易,而且还允许控制流,我们可以使用 $? 读取脚本或程序的退出状态。这允许 bash 脚本决定如果另一个脚本或程序异常退出时该怎么做。

为Shell脚本中的文本着色

Linux: How to colorize text in bash scripts

Shell脚本调试

在 Shell 脚本中,可以使用 exit 命令来终止脚本的执行。exit 命令会立即停止脚本的运行,并可以选择性地返回一个状态码。

你可以选择性地提供一个状态码,例如 exit 1,表示脚本以错误状态退出。

文件备份与同步

  1. 创建硬链接

  2. 使用操作系统的文件同步工具

    • Windows: 使用robocopy命令。

      创建一个批处理脚本来定期同步文件:

      1
      2
      3
      4
      5
      6
      7
      @echo off
      set src_file="C:\path\to\your\file.txt"
      set dest_file="D:\path\to\backup\folder\file.txt"
      :loop
      robocopy %src_file% %dest_file% /MIR
      timeout /t 60
      goto loop
    • Linux: 使用rsync命令。

      创建一个Shell脚本来定期同步文件:

      1
      2
      3
      4
      5
      6
      7
      #!/bin/bash
      src_file="/path/to/your/file.txt"
      dest_file="/path/to/backup/folder/file.txt"
      while true; do
      rsync -av --delete "$src_file" "$dest_file"
      sleep 60
      done
  3. 使用文件系统监控工具

    你可以使用Python中的watchdog库来监控文件的更改,并在文件发生更改时自动复制到备份文件夹。

    1
    pip install watchdog

    编写Python脚本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    import time
    import shutil
    from watchdog.observers import Observer
    from watchdog.events import FileSystemEventHandler

    class FileChangeHandler(FileSystemEventHandler):
    def __init__(self, src_path, dest_path):
    self.src_path = src_path
    self.dest_path = dest_path

    def on_modified(self, event):
    if event.src_path == self.src_path:
    shutil.copy2(self.src_path, self.dest_path)
    print(f"File {self.src_path} has been backed up to {self.dest_path}")

    def monitor_file(src_path, dest_path):
    event_handler = FileChangeHandler(src_path, dest_path)
    observer = Observer()
    observer.schedule(event_handler, path=src_path, recursive=False)
    observer.start()
    try:
    while True:
    time.sleep(1)
    except KeyboardInterrupt:
    observer.stop()
    observer.join()

    if __name__ == "__main__":
    src_file = "path/to/your/file.txt"
    dest_file = "path/to/backup/folder/file.txt"
    monitor_file(src_file, dest_file)
  4. 使用云存储服务。你可以使用云存储服务(如Dropbox、Google Drive、OneDrive等)来自动同步文件。将文件放在云存储的同步文件夹中,云存储服务会自动同步文件到云端和其他设备。

在bash终端窗口查看上一个命令的开始位置

在 Linux 的终端中,没有直接的命令可以一键跳转到上一个命令的开始位置,因为终端主要是一个输出流,并没有内置的“标记位置”或“跳转到输出开头”的功能。然而,可以通过以下方法间接实现类似的功能:

使用终端滚动功能

大多数终端(例如 Ubuntu 的默认终端 gnome-terminal)支持滚动查看之前的输出:

  • 快捷键:
    • Ctrl + Shift + ↑/↓:向上或向下滚动内容。
    • Shift + PageUp/PageDown:快速向上或向下翻页。
  • 鼠标滚轮:
    • 使用鼠标滚轮向上滚动查看之前的输出内容。

提前清屏

在运行耗时较长、输出较多的命令之前,手动清屏以标记起始位置。

  • 在终端窗口执行clear命令会清空屏幕,运行命令后,输出内容从清空后的顶部开始。
  • 当你想回到命令开头时,只需向上滚动到屏幕顶部。

“Ctrl+L”类似于clear命令,但并不会真正删除屏幕后面的内容,只是将光标移到屏幕顶部,并清空可见区域。

标记开始位置

  1. 在运行命令之前,打印一个明显的分隔符,方便在输出中快速找到起点。

    1
    echo "========== Start =========="
  2. 打开终端的搜索功能“Ctrl+Shift+F”并输入关键字(例如 ========== Start ==========),快速定位到命令开头。

  3. 完成。

将输出重定向到文件

如果你执行的命令输出非常多,可以提前将其输出保存到文件中,方便后续查看。

1
your_command > output.txt

Windows

快捷键

快捷键 作用 自定义
虚拟桌面
Win+Ctrl+D 创建新的虚拟桌面,并切换到它
Win+Ctrl+<-/-> 切换桌面 Ctrl+Alt+↑/↓
Win+Tab(或Alt+Tab且按住Alt) 打开任务视图
窗口
Ctrl+N 新建当前窗口
Ctrl+Shift+N 新建文件夹
Win+D 将所有打开的窗口最小化,并转到桌面,再次按下即刻恢复所有内容
Win+<-/-> 可以自动将应用窗口完全贴靠到屏幕两侧
Win+ ↑ 可以将应用窗口最大化
Win+ ↓ 可以将应用窗口最小化。若是当前窗口处于最大化状态,则按住 Win 键不放,连续按两下 ↓ 键即可将窗口最小化。
Win+V 查看剪切板历史

其它一些可参考Linux快捷键

其它:

  1. 将窗口移动到另一个虚拟桌面(不幸的是,Windows不包括直接用于在虚拟桌面之间移动窗口的键盘快捷键):Win+Tab打开任务视图后,使用鼠标拖动应用窗口到另一个虚拟桌面。
  2. Windows 10 系统 Win+<-/-> 分屏失效处理方法:控制面板-外观和个性化-轻松使用设置中心-使鼠标更易于使用-取消勾选"将窗口移动到屏幕边缘时不要自动排列窗口"。
  3. 设置快捷键:开始菜单-找到“Anaconda Powershell Prompt”-右键:打开文件位置-属性-快捷方式-快捷键:Ctrl+Alt+T。

Powershell

  1. Powershell 配置 alias:

    1. 打开 Powershell,执行echo $PROFILE命令,确定新建文件的名称和位置。

    2. 例如:在C:\Users\username\Documents\WindowsPowerShell文件夹下新建Microsoft.PowerShell_profile.ps1文件。

    3. 按格式输入命令:

      1
      2
      function 别名 { 需要替代的命令 }
      Set-alias 's' 'Select-Object'
    4. 以管理员身份打开Powershell 执行命令:

      1
      2
      Set-ExecutionPolicy RemoteSigned
      # `Set-ExecutionPolicy RemoteSigned` 是一个 Windows PowerShell 命令,用于设置 PowerShell 执行策略。执行策略用于控制是否允许在系统上运行脚本,以及允许哪些来源的脚本运行。
    5. 重启Powershell。

  2. Powershell 执行多条命令:

    1
    2
    3
    # 在powershell7上已经支持&&操作,如低于该版本请继续往下看
    (mkdir test) -and (cd test)
    mkdir test;cd test
  3. 将cmd/powershell中的打印信息输出保存为txt文本文件:

    1
    ping www.baidu.com >D:/log.txt

    保存界面上已经执行过的输出内容:点击powershell左上角的下三角形,或直接Ctrl+Shift+P打开命令面板,找到“导出文本”选项,确认保存位置。

  4. 打开网址:

    1
    2
    3
    4
    # starts with default browser and adds to open browser
    Start-Process -FilePath www.google.com
    # starts with a specific browser
    Start-Process -FilePath iexplore -ArgumentList www.google.com
  5. 等等。

命令

复制文件(夹)

robocopy

发现如果直接在桌面拖动文件夹进行复制,如果被复制的文件夹内有不正常的文件,整个复制过程就不会被执行。因此,使用命令行执行复制操作。原意是查看是哪个文件破坏了整个复制过程,结果发现可以直接跳过不正常的文件。

1
robocopy <source> <destination> [<file>[ ...]] [<options>]

最好以管理员方式启动终端?以保证复制过程没有文件权限问题。

无论文件夹路径最后加不加\,都是将 source 文件夹下的内容复制进 destination 文件夹,而不是复制进 source 文件夹本身。所以要提前新件号 destination 文件夹。

官方文档

  • source: 指定源目录的路径。
  • destination: 指定目标目录的路径。
  • file: 指定要复制的一个或多个文件。支持通配符( *? )。如果不指定此参数,则使用*.*作为默认值。
  • options:指定与robocopy命令一起使用的选项,包括copyfileretryloggingjob选项。
    • /s: 复制子目录。此选项自动排除空目录。
    • /e: 复制子目录。此选项自动包含空目录。
    • /v: 生成详细输出,并显示所有跳过的文件。
    • /mt:<n>: 创建具有n 个线程的多线程副本。 n必须是 1 到 128 之间的整数。n的默认值为 8。为了获得更好的性能,请使用/log选项重定向输出。(慎用,如果遇到复制错误的文件,会卡在那里重复尝试)
1
robocopy "C:\source_folder" "D:\destination_folder" /e /v

复制大量小文件

如果你要复制的文件夹内包含大量小文件,可以考虑以下几种方法来提高复制效率:

  1. 使用 robocopy 的多线程选项

    robocopy 支持多线程复制,可以显著提高复制大量小文件的速度。

    1
    robocopy "C:\source_folder" "D:\destination_folder" /e /mt:16

    就算不用多线程也很快。

  2. 压缩文件夹再复制

    将文件夹压缩成一个压缩文件(如 .zip),然后复制压缩文件,最后在目标位置解压。这种方法可以减少文件系统的开销。

    1
    2
    3
    Compress-Archive -Path "C:\source_folder" -DestinationPath "C:\source_folder.zip"  # 使用 PowerShell 压缩文件夹
    copy "C:\source_folder.zip" "D:\destination_folder.zip" # 复制压缩文件
    Expand-Archive -Path "D:\destination_folder.zip" -DestinationPath "D:\destination_folder" # 使用 PowerShell 解压文件夹
  3. 使用第三方工具

    一些第三方工具如 FastCopyTeraCopy 专门优化了文件复制过程,特别是对于大量小文件的复制。

    1
    2
    3
    # 下载并安装 FastCopy。
    # 使用命令行进行复制
    fastcopy.exe /cmd=diff /auto_close "C:\source_folder" /to="D:\destination_folder"
  4. 使用 rsync(适用于 Windows Subsystem for Linux)

    如果你在 Windows 上安装了 WSL,可以使用 rsync,它在处理大量小文件时表现良好。

    1
    rsync -av --progress /mnt/c/source_folder /mnt/d/destination_folder

选择适合你的方法来提高复制大量小文件的效率。

定时关机

https://learn.microsoft.com/de-de/windows-server/administration/windows-commands/shutdown

Win11怎么设置自动关机?Win11使用shut down命令自动关机的方法

允许您一次关闭或重新启动一台本地计算机或远程计算机。

1
2
3
4
5
6
shutdown -help  # 显示用法
shutdown -i # 显示图形用户界面(GUI)
shutdown -s -t 3600 # 3600秒后关机
shutdown -r -t 3600 # 3600秒后重启
shutdown -h # 休眠
shutdown -a # 取消关机,或者取消重启

还可以按 Win+R 快捷键后,在“打开”处输入at 16:00 shutdown -s。(TODO)

小贴士

设置/重映射快捷键

  1. PowerToysKeyboard Manager工具。

  2. 添加快捷方式,右键快捷方式-属性-快捷键。参考链接

    解决快捷键反应延迟问题:

    • Win10:win+s搜索后台应用-打开后台应用,将“设置“一栏关闭即可。参考链接
    • Win11:按下Win键打开开始菜单-所有应用-找到“设置”-右键-更多-应用设置-后台组件权限:从不(默认为电源已优化(推荐))。参考链接

下载

  • Windows系统下也可以运行Linux系统下的*.sh脚本/命令。网上有解决办法,例如;或者把shell脚本语言转为Powershell脚本语言。

    • 在Powershell下使用Invoke-WebRequest命令下载文件很慢。网上有解决方法,例如
    • Powershell下可以使用wgetcurl等命令。
  • 使用IDM、迅雷等下载器。

    • IDM

      • 优点:(分块)下载速度快(比浏览器默认下载快);定时下载;(使用通配符)添加批量任务;运行站点抓取;资源嗅探

      • 缺点:收费;(大文件)分块下载后合并下载块慢(解决:设置单线程下载;下载的临时文件夹和“保存至”文件夹不要在同一块硬盘上;高配电脑(CPU和SSD))

        • 改成单线程的话,该文件下载速度会变慢。当然,如果你同时下载许多个文件,那么可以这么做,不影响。
        • 同盘剪切一定快于跨盘剪切,但同盘复制一般慢于跨盘复制。
    • 迅雷

      • 优点:定时下载;下载速度快
      • 缺点:国产软件……想要速度快需要开会员

其它

  1. Anaconda Prompt与Anaconda PowerShell Prompt与系统cmd与powershell的区别:

    • cmd
      • 优点:无
      • 缺点:Python不行;ls不行
    • Powershell
      • 优点:ls
      • 缺点:Python不行
    • Anaconda Prompt
      • 优点:Python 行
      • 缺点:ls不行
    • Anaconda Powershell Prompt【完美】
      • 优点:Python 行、ls
      • 缺点:无
  2. 导入环境变量:搜索“环境变量”——新建。

  3. 在 Windows PowerShell 终端中打开当前终端所在的文件夹:

    1
    explorer .
  4. 等等。

其它

3-2-1备份规则

3-2-1 备份策略

3-2-1 备份规则是一种简单、有效的策略,可确保数据安全。它建议您将数据的三份副本保存在两个不同的介质上,其中一份副本保存在异地。让我们来分解一下:

  • 数据的三份副本:您的三份副本包括原始数据或生产数据以及另外两份副本。
  • 两种不同的介质上:您应该将数据存储在两种不同形式的介质上。这在今天意味着与 2000 年代末有所不同。我稍后会详细讨论这一点。
  • 一份异地副本:您应该在异地远程位置保存一份数据副本,最好距离其他两份副本几英里远。

如果您想保护您的个人信息、照片、工作文件或其他重要数据,3-2-1 备份策略是您的最佳选择。它可以帮助您避免出现容易受到人为错误、硬盘驱动器崩溃、盗窃、自然灾害或勒索软件影响的单点故障。``

文件(夹)命名

命名规范

为了确保日常使用的方便与系统兼容性,个人电脑上的文件夹和文件命名应遵循一定的规范。以下是一些通用的指导原则和最佳实践:

  1. 简洁明了:命名应简单且直接表达文件内容或文件夹用途,避免过长或含糊不清的名称。
  2. 避免使用特殊字符:一般来说,文件名中不应包含如下字符:\/:*?"<>|。这些特殊字符在多数操作系统中有特定用途,可能导致错误或不被识别。
  3. 使用合适的文件扩展名:文件扩展名反映了文件的类型,如 .txt 表示文本文件,.jpg 表示JPEG图像文件。正确的扩展名有助于操作系统正确识别和打开文件。
  4. 利用日期和版本控制:在文件名中包含日期(如 2023-03-15)可以帮助管理文件版本。对于频繁更新的文档,可能还需要添加版本号(如 v1.0v2.0)。
  5. 避免空格:虽然大多数现代操作系统可以很好地处理文件名中的空格,但在某些情况下(如命令行操作或网络传输)可能会引起问题。可以使用下划线(_)或破折号(-)来代替空格。
  6. 区分大小写:虽然Windows系统的文件名不区分大小写,但Linux和macOS区分大小写。为了兼容性,最好在命名时注意大小写的一致性。
  7. 组织性和易读性:对于包含多个文件的文件夹,可以采用有组织的命名体系,如按功能、日期或项目分类。
  8. 国际化和本地化:如果你的文件可能会被不同语言的用户访问,避免使用特定语言的字符,尽量使用英文和国际通用的符号。

遵循这些基本原则可以帮助提升文件管理的效率和降低因命名不当引起的问题。如果有特定的组织或项目命名规则,也应优先遵守这些专业指导标准。

命名方法

整词用驼峰或下划线_命名,整词间用-分隔。

在个人电脑上命名文件夹和文件时,虽然没有像编程语言那样严格的命名规范,但仍可以借鉴一些编程中的命名方法来组织文件,使其更加有序和易于管理。以下是一些常见的命名方法,以及如何将它们应用于文件和文件夹的命名:

  1. 小驼峰式命名法 (lowerCamelCase):
    • 应用: 适用于文件名,尤其是在需要保持名称简洁且连贯的情况下。
    • 示例: personalBudget.xlsx, summerVacationPhotos.jpg
  2. 大驼峰式命名法 (UpperCamelCase):
    • 应用: 适合用于较重要的文件和项目文件夹,特别是在编程项目中。
    • 示例: ProjectReport2023.docx, TaxDocuments2023
  3. 下划线命名法 (snake_case):
    • 应用: 适用于需要强调易读性的情况,也有助于避免在使用某些操作系统和环境时出现问题。
    • 示例: final_report_2023.pdf, holiday_photos_2022
  4. 破折号命名法 (kebab-case):
    • 应用: 更常见于网页文件和资源,但也可以用于普通文件和文件夹。
    • 示例: end-of-year-summary-2023.pdf, project-budget-2023.xlsx
    • 注意: 文件系统如Windows和记录系统通常对破折号支持良好,但在某些命令行环境中可能会遇到解释上的问题。
  5. 日期前缀命名:
    • 应用: 对于需要按日期管理的文档或文件,如财务文件或定期报告。
    • 示例: 2023-01-30_MeetingNotes.docx, 2023-03-15_Invoice.pdf

选择哪种命名方法取决于个人偏好、所处的工作环境以及是否需要跨平台交互。例如,如果在一个环境中主要用Python编程,那么使用snake_case可能更自然。而如果是在处理法律或业务文档,使用UpperCamelCase或日期前缀可能更为合适。

无论选择哪种命名方法,重要的是保持一致性,这样可以减少寻找和管理文件的时间,也能使文件系统更加有序。

下划线_与短划线-的对比

特点 下划线 _ 短划线 -
命名风格 常用于变量名、文件名(snake_case)。 常用于文件名、URL(kebab-case)。
双击选中行为 双击时会选中整个包含下划线的字符串。 双击时只选中单个单词。
可读性 下划线在代码中更容易识别为分隔符。 短划线在命令行或文件名中更直观。
使用场景 编写代码(变量名、函数名)。 文件名、URL 或配置文件中的键。
键盘输入 需要按住 Shift 键(Shift + -)。 直接输入,无需按住 Shift 键。
技术限制 不适用于某些文件系统或 URL(下划线合法但不常用)。 短划线在变量名中不被编译器支持(如 C++)。
  • 在很多编程语言中,_ 是合法的变量名分隔符,而 - 不是。
  • 在文件系统中,_ 通常比 - 更常用,尤其是在需要跨平台(Windows、Linux、macOS)兼容的情况下:
    • 某些旧系统可能会错误解析 -
    • - 在命令行中容易被误解为选项前缀(例如 ls -a)。
  • 短划线更适合文件名和 URL,因为它们在视觉上更易分辨。
  • 如果你更倾向于使用下划线 _ 但希望解决双击选中全部字符串问题,可以通过配置编辑器的行为来优化。

表示存放未修改的源文件的文件夹

如果一个文件夹存放的是未修改的源文件(例如来自第三方库或外部依赖),常见的命名方式包括:

  • vendor/
    • 常见于包含第三方库的代码,例如在前端项目或后端依赖管理中。
    • 例如:vendor/react, vendor/bootstrap.
  • third_party/thirdparty/
    • 表示存放来自第三方的代码或库。
    • 例如:third_party/libpng, third_party/zlib.
  • external/
    • 用于存放外部依赖项,强调这些文件是外部的而且未修改。
    • 例如:external/protobuf, external/sqlite.
  • original/src/
    • 如果这些源文件是项目的一部分,但未经过修改,original/ 表示它们是原始版本。
    • 例如:original/images, src/original_code

表示额外的、杂的、不属于其他文件夹分类的文件

在软件开发中,如果需要一个文件夹存放一些 额外的、杂的、不属于其他文件夹分类的文件,通常会使用以下命名方式:

  • misc/(最常见)

    • 含义:表示 "miscellaneous"(杂项、其他)。

    • 用途:存储那些不容易归类到其他文件夹的文件。

  • miscellaneous/

    • 含义miscellaneous 是 "misc" 的完整拼写形式。
    • 用途:与 misc/ 类似,但更正式。
  • other/

    • 含义:表示 "other files"(其他文件)。
    • 用途:存储那些不属于其他分类的文件。
  • extra/

    • 含义:表示 "extra files"(额外文件)。
    • 用途:表示一些附加文件,通常是非核心文件或附加的内容。
  • temp/

    • 含义:表示临时文件(temporary)。
    • 用途:如果这些杂项文件是临时性的或供短期使用,可以存放在 temp/ 文件夹。

表示一个文件是另一个文件的备份

备份文件的命名方式通常遵循几个规则,以清晰地表示其来源和目的:

  • 使用后缀 .bak(常见于备份文件):
    • 例如:config.json.bak
    • 表示 config.json 文件的备份版本。
  • 在文件名中添加 backup
    • 例如:config_backup.json
    • 清楚地表明这是一个备份文件。
  • 添加时间戳
    • 例如:config_20250423.jsonconfig_backup_20250423.json
    • 通过时间戳标记备份的创建时间,方便管理多个备份。
  • 命名模板:original_filename.bak, original_filename.timestamp
    • 例如:
      • data.csv.bak
      • data_20250423.csv

中文文本中夹用英文时,是否要留有空格

推荐留空,方便整词选择。如果不留空,选择时可能会选择夹杂中英文的整行而不是单个英文单词。

中文文本中夹用英文时,应根据所选用的中英文字体、字符间距以及排版的视觉效果决定英文词句与中文文字之间是否留有空格间距。如留空格,应保证体例的统一。——中华人民共和国新闻出版行业标准CY/T 154—2017号《中文出版物夹用英文的编辑规范》第8.1节

  • 但同时我更鼓励各类排版引擎自动在用户没有显式输入空格字符的情况下,也在中英文词汇间产生适当的间距。现在有一些已经做到了,比如 iOS 系统、微信、Microsoft 办公软件等。

浏览器搜索操作符

可以直接用此网址,不需要记命令,它自动组装为命令:

语法:

  • 整词搜索:双引号。示例:"关键词"
  • 逻辑与:空格。示例:关键词1 关键词2
  • 逻辑或:空格OR空格。示例:关键词1 OR 关键词2
  • 逻辑非:空格-(减号前面必须是空格,减号后面没有空格,要紧跟着需要排除的词)。示例:关键词 -排除词
  • 模糊搜索:*(通配符,匹配任意词或短语)。示例:国家* 匹夫*
  • 指定网站:关键词 site:网站地址。注意:“site:”后面跟的站点域名,不要带“http://”。site:和站点名之间,不要带空格。示例: 编程教程 site:blog.csdn.net
  • 排除指定网站:关键词 -site:网站地址。示例:编程教程 -site:blog.csdn.net

中英文版本的简称

当描述一个文件是中文版本时,通常使用的语言代码有几种不同的形式,主要取决于具体的语境和标准。最常见的是“zh”,这是ISO 639-1标准下的代码,用于表示中文。然而,如果需要指明具体是简体中文还是繁体中文,人们可能会使用“zh-CN”(中国大陆使用的简体中文)和“zh-TW”(台湾地区使用的繁体中文)。这些是基于IETF语言标签(由ISO 639和ISO 3166国家代码组合而成),广泛用于网站和软件本地化中。

对于英文版本,通常使用的语言代码为“en”,这同样遵循ISO 639-1标准。如需进一步区分不同地区的英语,例如美国英语和英国英语,则分别使用“en-US”和“en-GB”。

这些缩写在多语言处理、软件本地化、网页语言标签等方面非常重要。选择正确的代码有助于正确设置语言环境,确保内容正确呈现给目标用户群体。如果有更具体的用途,如编程、文件标签或其他,请提供详细信息,以便提供更精确的建议。

命令行参数设计

在命令行参数设计中,使用一个短划线(-v)还是两个短划线(--v)取决于参数的用途和常见的命令行约定。以下是它们的区别和使用场景:

  • 单短划线(-v
    • 使用一个短划线通常表示短选项
    • 短选项通常是单个字母,简洁易用,例如:
      • -v(verbose,启用详细输出)
      • -h(help,显示帮助信息)
    • 短选项可以组合在一起。例如,-abc相当于-a -b -c
    • 短选项适合经常使用的参数,因为打字很快。
  • 双短划线(--v--verbose
    • 使用两个短划线表示长选项
    • 长选项通常是一个完整的单词或短语,便于理解,例如:
      • --verbose(启用详细输出)
      • --help(显示帮助信息)
    • 长选项通常不允许组合,必须单独列出。
    • 长选项更适合不常用的参数,或者需要更清晰语义的场景
  • 最佳实践是同时支持短选项和长选项,为用户提供灵活性。

截取屏幕的固定区域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import argparse
from PIL import ImageGrab # pip install pillow

def capture_fixed_area(left, top, right, bottom, output_file="screenshot.png"):
# 定义截图区域(left, top, right, bottom)
bbox = (left, top, right, bottom)

# 截图
screenshot = ImageGrab.grab(bbox)

# 保存截图到文件
screenshot.save(output_file)

print(f"截图已保存到: {output_file}")

if __name__ == "__main__":
# 设置命令行参数解析
parser = argparse.ArgumentParser(description="Capture a specific area of the screen.")
parser.add_argument("left", type=int, help="Left coordinate of the rectangle.")
parser.add_argument("top", type=int, help="Top coordinate of the rectangle."
parser.add_argument("right", type=int, help="Right coordinate of the rectangle."
parser.add_argument("bottom", type=int, help="Bottom coordinate of the rectangle.")
parser.add_argument(
"--output_file", type=str, default="screenshot.png", help="Path to save the screenshot (default: screenshot.png)." 
)

# 解析命令行参数
args = parser.parse_args()

# 调用截图函数
capture_fixed_area(args.left, args.top, args.right, args.bottom, args.output_file)

使用以下命令运行脚本,并传递截图的区域坐标和输出文件路径:

1
python capture_fixed_area_with_cli.py 700 300 1200 1180 --output_file fixed_area_screenshot.png

系统常用命令及快捷键
http://zeyulong.com/posts/a8aab215/
作者
龙泽雨
发布于
2024年3月5日
许可协议