echo
# 系统指令
$ echo $(pwd) # 对于系统自带的pwd,此处不能写echo $pwd
# 自定义变量
$ foo=$(pwd)
$ echo $foo # 不同于pwd,对于自定义的foo,不能用$(foo)
!!
# 假设你先执行了以下原本需要权限的指令
$ mkdir /mnt/xuyang
# 终端立即提示你:Permission denied,这时可通过如下指令进行简化:【!!默认指代上次指令内容】
$ sudo !! # 该句等效于:sudo mkdir /mnt/xuyang
rm
与rmdir
# rmdir 仅用于删除空目录,如果要删除非空目录,需要使用 rm 命令
# rm -rf会递归地删除目录及其所有子目录和文件。选项 -r 表示递归删除,选项 -f 表示强制删除,即不提示确认。
$ rm -rf directory/
&&、||
# shell脚本也可以执行逻辑指令
# &&前面为真,故会正常echo
$ true && echo "hello peter parker"
# &&前面为假,故后面的echo不会执行
$ false && echo "hello peter parker"
# 逻辑或同理
""
与''
# 单引号和双引号的区别
# 双引号时输出:hello, I am in /home/xuyang
$ echo "hello, I am in $(pwd)"
# 双引号时输出:hello, I am in $(pwd)
$ echo 'hello, I am in $(pwd)'
# 拓展:$()是一种命令替换(command substitution)语法,用于将命令的输出结果作为变量的值进行引用。在$()中引用的变量可以是任何在命令中使用的变量或者环境变量。
|、||
# | 和 || 是两个不同的操作符,分别表示管道和逻辑或。
# | 用于将多个命令的输出连接起来进行数据流处理,而 || 用于在条件语句中指定多个条件中的任意一个满足即可执行相应的操作。
$0、$1、$2、$#、$$、$@、$?
# 在 Linux 系统中,$0 是一个特殊的变量,用于表示当前执行的脚本或命令的名称。
# 例如,在一个名为myscript.sh的bash脚本:
[
#!/bin/bash
echo "当前脚本的名称及路径为:$0"
]
# 当使用 ./myscript.sh 命令执行这个脚本时,
$ ./myscript.sh
# 输出的结果为:当前脚本的名称及路径为:./myscript.sh
# 此外,如果需要获取脚本或命令的参数或选项,可以使用 $1、$2、$3 等等来表示对应的参数或选项,例如:
# 例如,在一个名为myscript.sh的bash脚本:
[
#!/bin/bash
echo "当前脚本的第一个参数为:$1"
]
# 当使用 ./myscript.sh hello 命令执行这个脚本时,
$ ./myscript.sh hello
# 输出的结果为:当前脚本的第一个参数为:hello
# $# 是一个特殊的变量,用于表示传递给脚本或函数的参数个数。具体来说,$# 表示命令行上给出的参数个数,但不包括命令本身。
# $@ 是一个特殊的变量,用于表示传递给脚本或函数的所有参数列表,每个参数都是一个独立的字符串。具体来说,$@ 表示所有参数列表,但不包括命令本身。
# $$ 是一个特殊的变量,用于表示当前进程的进程ID号(PID),即 Shell 或脚本本身的进程 ID。具体来说,$$ 表示当前进程的ID,是一个整数值。
# 在Ubuntu中,echo $?是一个命令,用于显示上一个命令的退出状态码(Exit status code)。每个命令在执行完成后都会返回一个退出状态码,来表示命令执行的结果。0表示成功,非0值表示失败或错误。
$ echo $?
grep
# grep 命令用于在文本文件中查找匹配的字符串:grep [options] pattern [file ...]
# 其中,options为可选参数,pattern为要查找的字符串或正则表达式,file为要查找的文件名。如果省略 file 参数,则默认从标准输入中读取数据进行匹配。
# 下面是 grep 命令的一些常见选项:
# -i:忽略大小写进行匹配。
# -v:反向匹配,输出不匹配的行。
# -w:匹配整个单词,而不是匹配字符串的一部分。
# -r:递归查找指定目录下的所有文件。
# -n:输出匹配行的行号。
# -c:仅输出匹配行的数量,而不是具体的匹配内容。
# 在文件file.txt中查找包含字符串 "hello" 的行
grep "hello" file.txt
# 在多个文件中查找包含字符串 "hello" 的行
grep "hello" file1.txt file2.txt file3.txt
# 在文件 `file.txt` 中查找包含字符串 "hello" 的行,忽略大小写
grep -i "hello" file.txt
# 在文件 `file.txt` 中查找不包含字符串 "hello" 的行
grep -v "hello" file.txt
# 在文件 `file.txt` 中查找包含整个单词 "hello" 的行
grep -w "hello" file.txt
# 在目录 `/path/to/directory` 及其子目录中递归查找包含字符串 "hello" 的行
grep -r "hello" /path/to/directory
# 在文件 `file.txt` 中查找包含字符串 "hello" 的行,并输出行号
grep -n "hello" file.txt
# 在文件 `file.txt` 中查找包含字符串 "hello" 的行,并输出匹配行的数量
grep -c "hello" file.txt
find
# 在某一目录下查找tools.txt文件
find /home/user/dir -name "tools.txt"
# 在某一目录下查找所有的.txt文件
find /home/user/dir -name "*.txt"
# 在某一目录下查找src文件夹(目录)
find /home/user/dir -name "src" -type d
locate
# 相比于find指令,locate的检索速度会快很多;默认在整个根目录(/)下进行搜索
# 在系统中查找是否存在某一文件夹或者文件,有的话会将绝对路径打印出来;如果没有输出任何信息,可以先updatedb一下
locate ros_ws
# 更新本地数据库后,可以再次查找
updatedb
shebang
# 在Linux系统中,shebang(也称为sha-bang或hashbang)是一种特殊的注释语法,用于指定脚本文件的解释器。shebang通常出现在脚本文件的第一行,其格式为:
#!interpreter [optional-arg]
# 其中,interpreter是用于解释脚本文件的程序或脚本解释器的路径,而optional-arg则是可选的参数,用于指定解释器的选项或参数。
# 这告诉系统在执行该脚本文件时,使用Bash解释器来解释该脚本文件。如果没有指定shebang,系统将默认使用/bin/sh作为解释器。
#!/bin/bash
convert
与ffmpeg
# convert:处理图像
# ffmpeg:处理视频
# tldr类似于man,查看某一指令的使用手册,tldr同时会给出一些使用范例,非常清晰易用!但那是需要先安装tldr
$ tldr convert
$ tldr ffmpeg
nnn
# 非常好用的终端文件管理器,功能强大,几乎零配置,具有令人难以置信的性能,可能是您使用过得最快的!可以在 DE 和 GUI 实用程序无缝集成,具有独特的导航即可模式、自动选择、可分析磁盘使用情况,批量重命名,启动应用程序和选择文件。
sudo apt install nnn
# 快捷键大全:
# d:默认左侧不显示每个目录/文件对应的时间戳,快捷键d可以切换显示
# j:往下启动选中项
# k:往上移动
# l(L键):进入下一级文件夹
# h:切换到上一级文件夹
# G/g:G:直接跳到最下面;g:直接跳到最上面
# e:编辑文件
# /:搜索内容,先按一下/,再输入待搜索的字符
# .:显示隐藏文件,来回切换
# space:选中文件
# 移动/复制文件到某一目录:先按一下【space键】即可选中(可以依次选中多个文件);移动到指定目录后,按一下【v】,即可完成移动过程;如果按一下【p】,即可完成复制过程!
# 删除文件:选中文件后,按一下【x】,根据提示需要【y】进行确认。
# 文件重命名:同时按【ctr+R】,输入新名称,回车即可。
# 左上角的【1,2,3,4】是不同的工作区,相互隔离,互不影响
nnn
管理器有很多独立的插件,比如图片/文本预览插件,可以到官方GitHub上下载安装,比较方便!tar
压缩
# 压缩包命名:archive.tar.gz
tar -czvf archive.tar.gz ./
解压
# 解压缩 .tar 文件
tar -xvf file.tar
# 解压缩 .tar.gz 或 .tgz 文件
tar -xzvf file.tar.gz
# 解压缩 .tar.bz2 文件
tar -xjvf file.tar.bz2
7z
解压img
在Ubuntu下,可以使用p7zip-full
软件包中的7z
命令来解压img文件;
安装p7zip-full
软件包:
sudo apt-get update
sudo apt-get install p7zip-full
解压
7z x filename.img
# 其中,`filename.img`是需要解压的img文件名。
# 如果img文件是多个分卷文件,可以使用以下命令来解压:
7z x filename.img.001
# 其中,`filename.img.001`是分卷文件的名称,`.001`表示第一个分卷文件。
dmesg
Linux dmesg(英文全称:display message)命令用于显示开机信息。kernel 会将开机信息存储在 ring buffer 中。您若是开机时来不及查看信息,可利用 dmesg 来查看。开机信息亦保存在 /var/log 目录中,名称为 dmesg 的文件里。
dmesg [-cn][-s <缓冲区大小>]
实例:
$ dmesg | less
WARNING: terminal is not fully functional
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Linux version 2.6.32-21-generic (buildd@rothera) (gcc version 4.4.3 (Ub
untu 4.4.3-4ubuntu5) ) #32-Ubuntu SMP Fri Apr 16 08:10:02 UTC 2010 (Ubuntu 2.6.32-21.3
2-generic 2.6.32.11+drm33.2)
[ 0.000000] KERNEL supported cpus:
[ 0.000000] Intel GenuineIntel
[ 0.000000] AMD AuthenticAMD
[ 0.000000] NSC Geode by NSC
[ 0.000000] Cyrix CyrixInstead
[ 0.000000] Centaur CentaurHauls
[ 0.000000] Transmeta GenuineTMx86
[ 0.000000] Transmeta TransmetaCPU
[ 0.000000] UMC UMC UMC UMC
[ 0.000000] BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: 0000000000000000 - 000000000009f800 (usable)
[ 0.000000] BIOS-e820: 000000000009f800 - 00000000000a0000 (reserved)
[ 0.000000] BIOS-e820: 00000000000ca000 - 00000000000cc000 (reserved)
[ 0.000000] BIOS-e820: 00000000000dc000 - 00000000000e0000 (reserved)
[ 0.000000] BIOS-e820: 00000000000e4000 - 0000000000100000 (reserved)
[ 0.000000] BIOS-e820: 0000000000100000 - 000000003fef0000 (usable)
[ 0.000000] BIOS-e820: 000000003fef0000 - 000000003feff000 (ACPI data)
[ 0.000000] BIOS-e820: 000000003feff000 - 000000003ff00000 (ACPI NVS)
……省略部分内容
htop
与iotop
通用监控工具 htop
,是 top
的改进版。htop
可以显示当前运行进程的多种统计信息;它有很多选项和快捷键,常见的有:
进程排序、 t
显示树状结构和 h
打开或折叠线程。
I/O 操作 - iotop
可以显示实时 I/O 占用信息而且可以非常方便地检查某个进程是否正在执行大量的磁盘读写操作;
$ htop
$ iotop
&>
与>&
&
和>
的区别:
&
:通常用于将一个命令放到后台运行,即在命令结尾处添加 &
符号;>
:重定向符,表示把前面输出的内容重定向到后面指定的位置;&>
和>&
的区别:
&>
:将命令的标准输出和标准错误输出都重定向到指定的位置,即同时重定向标准输出和标准错误输出;>&
:将标准输出或标准错误输出重定向到指定的位置。它的具体含义取决于它前面的数字是 1
(标准输出)还是 2
(标准错误输出);1>&2
和1>2
的区别:
1>&2
:1输出通道重定向到2输出通道,这里 &2
表示2输出通道;1>2
:
&
的加持,不能代表2输出通道。shell中的文件描述符:这里的数字0/1/2
是有特殊含义的!
STDIN
STDOUT
STDERR
举个栗子:
a.txt
:$ ls
a.txt
$ ls a.txt b.txt
ls: b.txt: No such file or directory # 由于没有b.txt这个文件, 于是返回错误值, 这就是所谓的2输出
a.txt # 而这个就是所谓的1输出
# 执行后没有任何返回值。原因是返回值都被重定向到相应的文件中了,想重定向谁,就写谁即可
$ ls a.txt b.txt 1>file.out 2>file.err
# 一般 `1>` 通常可以省略成 `>`,以下命令与上一命令等价
$ ls a.txt b.txt >file.out 2>file.err
$ cat file.out
a.txt
$ cat file.err
ls: b.txt: No such file or directory
file.out
文件:# 以下两条等价
$ ls a.txt b.txt 1>file.out 2>&1
$ ls a.txt b.txt &> file.out # 简洁版
$ cat file.out
ls: b.txt: No such file or directory
a.txt
;、&&、&
;
、&&
、&
隔开一起执行,但是作用有区别:
;
:有先后顺序,但是不管前面命令是否执行成功,后面的命令会紧接着执行;&&
:有先后顺序,并且要前面的命令执行成功后,才继续执行后面的命令;&
:所有命令同时执行,没有先后顺序。df、du
df
:显示每个分区的信息;du
:显示当前目录下每个文件的磁盘使用情况( disk usage)。-h
选项可以使命令以对人类(human)更加友好的格式显示数据;ncdu
是一个交互性更好的 du
,它可以让您在不同目录下导航、删除文件和文件夹;注意:%
并不是通配符;
# ? 任意单个字符
# * 任意0个或多个字符
# [ ] 匹配方括号中的任意一个字符,如[abc] 则匹配abc中的一个
# [ - ] "-"代表范围,例如:[a-z] 则匹配任意一个小写字母; [0-9] 则匹配任意一个0-9之间的数据,但是注意[0-10]不可以,不能超过9
# [^] 逻辑非,例如: [^0-9]匹配任意一个非数字字符
# 创建20个文件
for i in $(seq 1 1 20)
do
echo i > file${i}
done
# 删除file1 file2 ... file5
rm file[1-5]
touch a1 a2
# 删除a开头的所有文件
rm a*
# 删除a2 b2 c2
touch c1 c2
rm [abc]2
xdg-open
直接在命令行打开doc
、pdf
、png
等文件,不用在文件管理器中一层层找;
# 安装
sudo apt-get update
sudo apt-get install xdg-utils
xdg-open xxx.doc
xdg-open xxx.pdf
xdg-open xxx.png
xdg-open .
xdg-open ~/Downloads
xdg-open www.google.com
xargs
允许用户将标准输入的数据作为参数传递给其他命令,基本语法:
command | xargs [options] [command]
xargs
从标准输入读取数据,将其转换为命令行参数,并将其传递给 command
命令。
示例:
# 将文件列表传递给 rm 命令,以删除这些文件
find . -name "*.txt" | xargs rm
# 将列表中的URL下载到当前目录,从urls.txt文件中读取URL并将其逐行传递给curl -O命令,其中-n 1指定每次只传递一个参数给curl
cat urls.txt | xargs -n 1 curl -O
# 将多个文件合并成一个文件
find . -name "*.log" | xargs cat > all_logs.txt
如何理解Linux系统下的regular file?
在Linux系统中,regular file
是一种常见的文件类型,通常指的是普通的文本文件或二进制文件,其中包含了用户创建或下载的数据和程序代码等信息。
与之相对的是特殊文件(special file
),包括目录文件、设备文件、命名管道、符号链接等。
regular file
文件类型通常与其他文件类型进行区分,例如目录文件(directory)用于存储其他文件和目录的信息,设备文件(device file
)用于与硬件设备进行交互,命名管道(named pipe)用于进程间通信等。与之相比,regular file
文件类型的特点是具有一定的结构和格式,数据存储在文件中,并且可以被直接读取和编辑。
在Linux系统中,使用 ls -l
命令可以查看文件的详细信息,其中第一个字符表示文件类型,-
表示 regular file
文件类型。例如:-rw-r--r-- 1 user user 0 Jun 28 15:00 file.txt
在Linux系统中,file
命令可以用于识别文件类型,例如:file /bin/bash
/bin/bash
文件为ELF 64-bit LSB
可执行文件。在Linux系统中,source
命令和./
命令都可以用来执行脚本文件,但它们的执行方式和作用有所不同。
source
命令
source
命令用于在当前shell环境下执行指定的脚本文件,并将其内容作为当前shell
环境的一部分来处理。这意味着,脚本文件中定义的变量、函数和别名等将会在当前shell
环境中生效,可以在当前shell
环境中直接使用。使用source
命令执行脚本文件的语法如下:
source filename
# or
. filename
./
命令
./
命令用于在新的子shell环境下执行指定的脚本文件。这意味着,脚本文件中定义的变量、函数和别名等只会在子shell环境中生效,不会对当前shell环境产生影响。使用./命令执行脚本文件的语法如下:
./filename
source
命令可以将脚本文件的内容直接导入到当前shell
环境中,方便在当前shell环境中直接使用脚本中定义的变量和函数等;而使用./
命令则会在一个新的子shell
环境中执行脚本文件,适用于需要在独立的环境中执行脚本文件的情况。Tmux 就是会话与窗口的“解绑”工具,将它们彻底分离:
如上图所示,Tmux 采用 C/S 模型构建,输入 tmux 命令就相当于开启了一个服务器,此时默认将新建一个会话,然后会话中默认新建一个窗口,窗口中默认新建一个窗格(pane,面板)。会话、窗口、面板之间的联系如下:
session
(会话)可以包含多个window
(窗口),窗口默认充满会话界面,因此这些窗口中可以运行相关性不大的任务。window
又可以包含多个pane
(面板),窗口下的面板,都处于同一界面下,这些面板适合运行相关性高的任务,以便同时观察到它们的运行情况。二进制安装:
# Ubuntu 或 Debian
$ sudo apt-get install tmux
# CentOS 或 Fedora
$ sudo yum install tmux
# Mac
$ brew install tmux
源码安装:
git clone https://github.com/tmux/tmux.git
cd tmux
sh autogen.sh
./configure && make
直接在终端输入tmux
命令,即可直接进入 Tmux 窗口;
按下Ctrl+d
或者显式输入exit
命令,就可以退出 Tmux 窗口。
Ctrl+b
,即先按下Ctrl+b
,快捷键才会生效。Ctrl+b ?
:在 Tmux 窗口中,先按下Ctrl+b
,再按下?
,就会显示帮助信息。 ESC
键或q
键,就可以退出帮助。第一个启动的 Tmux 窗口,编号是0
,第二个窗口的编号是1
,以此类推。这些窗口对应的会话,就是 0 号会话、1 号会话。⚠️会话和窗口是不同的概念!
启动 Tmux 后,底部 [0] 表示第 0 个 Tmux 伪窗口,如果再启动一个 Tmux 伪窗口时则为 [1],依次递增。
但使用编号来区分会话,不太直观,更好的方法是为会话起名。
# 新建一个无名称的会话
$ tmux
# 新建一个指定名称的会话
$ tmux new -s <session-name>
底部不再是数字,而是命名的名字,如下图:
tmux ls
命令可以查看当前所有的 Tmux 会话:
$ tmux ls
# or
$ tmux list-session
如果刚好处于会话中,怎么查看所有会话?别担心,可以使用对应的 tmux 快捷键Ctrl+b + s
,此时 tmux 将打开一个会话列表,按上下键(⬆︎⬇︎)或者鼠标滚轮,可选中目标会话,按左右键(⬅︎➜)可收起或展开会话的窗口,选中目标会话或窗口后,按回车键即可完成切换:
在 Tmux 窗口中,按下Ctrl+b d
或者输入tmux detach
命令,就会将当前会话与当前窗口分离:
# 在 tmux 的任何一个窗格中输入如下命令
$ tmux detach
上面命令执行后,就会退出当前 Tmux 窗口,但是会话和里面的进程仍然在后台运行。
tmux attach
命令用于重新接入某个已存在的 Tmux 会话:
# 使用会话编号重新接入
$ tmux attach -t 0
# 使用会话名称重新接入
$ tmux attach -t <session-name>
tmux kill-session
命令用于杀死某个会话:
# 使用会话编号
$ tmux kill-session -t 0
# 使用会话名称
$ tmux kill-session -t <session-name>
# 关闭服务器,所有的会话都将关闭
$ tmux kill-server
tmux switch
命令用于切换会话:
# 使用会话编号
$ tmux switch -t 0
# 使用会话名称
$ tmux switch -t <session-name>
tmux rename-session
命令用于重命名会话:
# 将0号会话进行重命名
$ tmux rename-session -t 0 <new-name>
$ tmux rename-session -t old-session new-session
前缀 | 指令 | 描述 |
---|---|---|
Ctrl+b |
? |
显示快捷键的帮助文档 |
Ctrl+b |
d |
分离(断开)当前会话 |
Ctrl+b |
D |
选择要分离(断开)的会话 |
Ctrl+b |
Ctrl+z |
挂起当前会话 |
Ctrl+b |
r |
强制重载当前会话 |
Ctrl+b |
s |
显示会话列表用于选择并切换 |
Ctrl+b |
: |
进入命令行模式,此时可直接输入ls 等命令 |
Ctrl+b |
[ |
进入复制模式,按q 退出 |
Ctrl+b |
] |
粘贴复制模式中复制的文本 |
Ctrl+b |
~ |
列出提示信息缓存 |
tmux new -s my_session
。Ctrl+b d
将当前会话与窗口分离。tmux attach-session -t my_session
。tmux new-window
命令用来创建新窗口:
$ tmux new-window
# 新建一个指定名称的窗口
$ tmux new-window -n <window-name>
tmux select-window
命令用来切换窗口:
# 切换到指定编号的窗口
$ tmux select-window -t <window-number>
# 切换到指定名称的窗口
$ tmux select-window -t <window-name>
tmux rename-window
命令用于为当前窗口起名(或重命名):
$ tmux rename-window <new-name>
tmux kill-window
命令用于关闭当前窗口:
$ tmux kill-window -t <window-name>
窗口操作快捷键:
前缀 | 指令 | 描述 |
---|---|---|
Ctrl+b |
c |
新建窗口,状态栏会显示多个窗口的信息 |
Ctrl+b |
& |
关闭当前窗口(关闭前需输入y or n 确认);使用关闭窗格的命令亦可! |
Ctrl+b |
0~9 |
切换到指定编号的窗口 |
Ctrl+b |
p |
切换到上一窗口(按照状态栏上的顺序) |
Ctrl+b |
n |
切换到下一窗口 |
Ctrl+b |
w |
打开窗口列表,且用于切换窗口 |
Ctrl+b |
, |
重命名当前窗口 |
Ctrl+b |
. |
修改当前窗口编号(适用于窗口重新排序) |
Ctrl+b |
f |
快速定位到窗口(输入关键字匹配窗口名称) |
tmux select-pane
命令用来在不同窗格间进行选中切换:
# 光标切换到上方窗格
$ tmux select-pane -U
# 光标切换到下方窗格
$ tmux select-pane -D
# 光标切换到左边窗格
$ tmux select-pane -L
# 光标切换到右边窗格
$ tmux select-pane -R
tmux swap-pane
命令用来交换窗格位置:
# 当前窗格上移
$ tmux swap-pane -U
# 当前窗格下移
$ tmux swap-pane -D
# 左移、右移同理
`Ctrl+b x`:关闭当前窗格。
# or
`ctrl+d`,记住如果只有一个窗格就是关闭整个窗口了!
ctrl+b [
,再可以通过方向键上下滚动即可,或者使用PageUp
和PageDown
可以实现上下翻页。Ctrl+b %
:划分左右两个窗格,右侧新建面板。Ctrl+b "
:划分上下两个窗格,下侧新建面板。Ctrl+b
:光标切换到其他窗格。
是指向要切换到的窗格的方向键,比如切换到下方窗格,就按方向键↓
。Ctrl+b Space
:在自带的窗格布局中循环切换。Ctrl+b ;
:光标切换到上一个窗格。Ctrl+b o
:光标切换到下一个窗格。Ctrl+b {
:当前窗格与上一个窗格交换位置。Ctrl+b }
:当前窗格与下一个窗格交换位置。Ctrl+b Ctrl+o
:所有窗格向前移动一个位置,第一个窗格变成最后一个窗格。Ctrl+b Alt+o
:所有窗格向后移动一个位置,最后一个窗格变成第一个窗格。Ctrl+b x
:关闭当前窗格。Ctrl+b !
:将当前窗格拆分为一个独立窗口。Ctrl+b z
:当前窗格全屏显示,再使用一次会变回原来大小。Ctrl+b Ctrl+
:按箭头方向调整窗格大小。Ctrl+b q
:显示当前窗口下所有窗格的编号。PS:看到屏幕上会在每个窗格上显示出各自编号,此时迅速点击对应的编号,即可跳转到对应的窗格。Ctrl+b t
:显示时钟。# 列出所有快捷键,及其对应的 Tmux 命令
$ tmux list-keys
# 列出所有 Tmux 命令及其参数
$ tmux list-commands
# 列出当前所有 Tmux 会话的信息
$ tmux info
# 重新加载当前的 Tmux 配置
$ tmux source-file ~/.tmux.conf
详情请参考:
Github Repo
- Useful_tools -自定义软件配置
-Linux
-home
-xuyang
-.tmux.conf
&.config/tmux
。
powerline
等插件,具体安装过程可参考官方文档(对应的bilibili视频教学)。相信只要你用过几次 tmux,就会发现Ctrl+b
指令前缀,着实不太方便。这两个键相距太远,按键成本太高了。因此我们首先需要将它更换为距离更近的Ctrl+a
组合键,或者其他任意你喜欢的组合键。
Tmux 的用户级配置文件为~/.tmux.conf
(没有的话就创建一个),修改快捷指令,只需要增加如下三行即可:
set -g prefix C-a #
unbind C-b # C-b即Ctrl+b键,unbind意味着解除绑定
bind C-a send-prefix # 绑定Ctrl+a为新的指令前缀
# 从tmux v1.6版起,支持设置第二个指令前缀
set-option -g prefix2 ` # 设置一个不常用的`键作为指令前缀,按键更快些
修改的~/.tmux.conf
配置文件有如下两种方式可以令其生效:
Ctrl+b
指令前缀,然后按下系统指令:
,进入到命令模式后输入source-file ~/.tmux.conf
,回车后生效。既然快捷指令如此方便,更为优雅的做法是新增一个加载配置文件的快捷指令,这样就可以随时随地 load 新的配置了,如下所示:
# 绑定快捷键为r
bind r source-file ~/.tmux.conf \; display-message "Config reloaded.."
请特别注意⚠️,在已经创建的窗口中,即使加载了新的配置,旧的配置依然有效(只要你新加的功能没有覆盖旧的配置,因此如果你第一次绑定快捷指令为x
键,然后又改为绑定y
键,那么x
和y
都将有效),新建会话不受此影响,将直接采用新的配置。
既然我们已经迈出配置化的第一步,那么接下来我们可以做得更多。
tmux 中,使用最多的功能之一就是新增一个面板。水平方向新增面板的指令是 prefix
+ "
,垂直方向是 prefix
+ %
,"
和 %
需要两个键同时按下才能完成,加上指令前缀至少需要 3-4 次按键才能组成一个完整的指令,同时这个两个键也不够醒目和方便,因此我们可以绑定两个更常用的指令-
、|
,如下所示:
unbind '"'
bind - splitw -v -c '#{pane_current_path}' # 垂直方向新增面板,默认进入当前目录
unbind %
bind | splitw -h -c '#{pane_current_path}' # 水平方向新增面板,默认进入当前目录
默认情况下,tmux 的多窗口之间的切换以及面板大小调整,需要输入指令才能完成,这一过程,涉及到的指令较多,而且操作麻烦,特别是面板大小调整,指令难以一步到位,这个时候开启鼠标支持就完美了。
对于 tmux v2.1 (2015.10.28) 之前的版本,需加入如下配置:
setw -g mode-mouse on # 支持鼠标选取文本等
setw -g mouse-resize-pane on # 支持鼠标拖动调整面板的大小(通过拖动面板间的分割线)
setw -g mouse-select-pane on # 支持鼠标选中并切换面板
setw -g mouse-select-window on # 支持鼠标选中并切换窗口(通过点击状态栏窗口名称)
有的地方可能会出现set-window-option
的写法,setw
就是它的别名。
对于 tmux v2.1 及以上的版本,仅需加入如下配置:
set-option -g mouse on # 等同于以上4个指令的效果
需要注意的是,开启鼠标支持后,iTem2 默认的鼠标选中即复制功能需要同时按下 Alt
键,才会生效。
鼠标支持确实能带来很大的便捷性,特别是对于习惯了鼠标操作的 tmux 新手,但对于键盘爱好者而言,这不是什么好消息,对他们而言,双手不离键盘是基本素质。
虽然指令前缀加方向键
可以切换面板,但方向键
太远,不够快,不够 Geek。没关系,我们可以将面板切换升级为熟悉的h
、j
、k
、l
键位。
# 绑定 h、j、k、l 键为面板切换的上、下、左、右键
bind -r k select-pane -U # 绑定k为↑
bind -r j select-pane -D # 绑定j为↓
bind -r h select-pane -L # 绑定h为←
bind -r l select-pane -R # 绑定l为→
-r
表示可重复按键,大概 500ms 之内,重复的h
、j
、k
、l
按键都将有效,完美支持了快速切换的 Geek 需求。
除了上下左右外, 还有几个快捷指令可以设置:
bind -r e lastp # 选择最后一个窗格(面板)
bind -r ^e last # 选择最后一个窗口,^e表示Ctrl+e
bind -r ^u swapp -U # 与前一个面板交换位置
bind -r ^d swapp -D # 与后一个面板交换位置
习惯了全键盘操作后,命令的便捷性不言而喻。既然面板切换的指令都可以升级,面板大小调整的指令自然也不能落后。如下配置就可以升级你的操作:
# 绑定Ctrl+h、j、k、l键为窗格上下左右调整边缘的快捷指令
bind -r ^k resizep -U 10 # 绑定Ctrl+k为往↑调整面板边缘10个单元格
bind -r ^j resizep -D 10 # 绑定Ctrl+j为往↓调整面板边缘10个单元格
bind -r ^h resizep -L 10 # 绑定Ctrl+h为往←调整面板边缘10个单元格
bind -r ^l resizep -R 10 # 绑定Ctrl+l为往→调整面板边缘10个单元格
以上,resizep
即resize-pane
的别名。
当窗口中面板的数量逐渐增多时,每个面板的空间就会逐渐减少。为了保证有足够的空间显示内容,tmux 从 v1.8 版本起,提供了面板的最大化功能,输入tmux-prefix + z
,就可以最大化当前面板至窗口大小,只要再重复输入一次,便恢复正常。那么 tmux v1.8 以下的版本,怎么办呢?别急,有大神提供了如下的解决方案。
首先编写一个 zoom 脚本,该脚本通过新建一个窗口,交换当前面板与新的窗口默认面板位置,来模拟最大的功能;通过重复一次按键,还原面板位置,并关闭新建的窗口,来模拟还原功能,如下所示:
#!/bin/bash -f
currentwindow=`tmux list-window | tr '\t' ' ' | sed -n -e '/(active)/s/^[^:]*: *\([^ ]*\) .*/\1/gp'`;
currentpane=`tmux list-panes | sed -n -e '/(active)/s/^\([^:]*\):.*/\1/gp'`;
panecount=`tmux list-panes | wc | sed -e 's/^ *//g' -e 's/ .*$//g'`;
inzoom=`echo $currentwindow | sed -n -e '/^zoom/p'`;
if [ $panecount -ne 1 ]; then
inzoom="";
fi
if [ $inzoom ]; then
lastpane=`echo $currentwindow | rev | cut -f 1 -d '@' | rev`;
lastwindow=`echo $currentwindow | cut -f 2- -d '@' | rev | cut -f 2- -d '@' | rev`;
tmux select-window -t $lastwindow;
tmux select-pane -t $lastpane;
tmux swap-pane -s $currentwindow;
tmux kill-window -t $currentwindow;
else
newwindowname=zoom@$currentwindow@$currentpane;
tmux new-window -d -n $newwindowname;
tmux swap-pane -s $newwindowname;
tmux select-window -t $newwindowname;
fi
不妨将该脚本存放在~/.tmux
目录中(没有则新建目录),接下来只需要绑定一个快捷指令就行:
unbind z
bind z run ". ~/.tmux/zoom"
试想这样一个场景:当你打开多个窗口后,然后想将其中几个窗口合并到当前窗口中,以便对比观察输出。
通过上面的 zoom 脚本,面板可以轻松地最大化为一个新的窗口。那么反过来,窗口是不是可以最小化为一个面板呢?
实际上,你的要求就是将其它窗口变成面板,然后合并到当前窗口中。对于这种操作,我们可以在当前窗口,按下tmux-prefix
+ :
,打开命令行,然后输入如下命令:
join-pane -s window01 # 合并名称为window01的窗口的默认(第一个)面板到当前窗口中
join-pane -s window01.1 # .1显式指定了第一个面板,.2就是第二个面板(我本地将面板编号起始值设置为1,如果你没有改的话,这里默认应该是0)
每次执行join-pane
命令都会合并一个面板,并且指定的窗口会减少一个面板,直到面板数量为0,窗口关闭。
除了在当前会话中操作外,join-pane
命令甚至可以从其它指定会话中合并面板,格式为join-pane -s [session_name]:[window].[pane]
,如join-pane -s 2:1.1
即合并第二个会话的第一个窗口的第一个面板到当前窗口,当目标会话的窗口和面板数量为0时,会话便会关闭。
注⚠️:上一节中的swap-pane
命令与join-pane
语法基本一致。