CMD说明

CMD说明

CMD字体要求

  • CMD/Powershell对字体要求比较严格

    • 等宽字体
    • 不能为斜体字体
    • 不能有A或C负空间
    • 若是TrueType字体,则必须是FF_MODERN
    • 若不是TrueType字体,则必须是OEM_CHARSET
  • 对于CJK(亚洲字体),还有额外附加条件

    • 若不是TrueType字体,字体名必须是Terminal
    • 若是TrueType字体,必须使用亚洲语言字符集
    • 在字体元信息里声明支持CP936

Tmux

Tmux

  • Session:用户与计算计算机的交互

    • 一般而言,temrinal窗口、Session进程绑定
      • 打开窗口,Session开始
      • 关闭窗口,Session结束
  • Tmux:终端复用软件,将terminal窗口、Session解绑

    • 允许多个窗口接入、断开多个Session
      • 新增多个Session
      • 接入已有Session,共享Session
    • 支持窗口竖直、水平拆分

https://man7.org/linux/man-pages/man1/tmux.1.html

命令行参数

  • -S <socket-file>:指定tmux使用socket文件(位置)

Session管理

  • tmux new -s <session-name>:创建指定名称session
    • 缺省数字命名
  • tmux detach:detach当前接入会话
  • tmux ls/list-session:列出session列表
  • tmux rename -t <s1> <s2>:重命名session
  • tmux a [-t <session-name>]:attach指定session
    • 缺省连接上个session
  • tmux switch -t <session-name>:切换至指定session
  • tmux kill-session [[-a] -t s1]:关闭session
    • 缺省关闭上次session
    • -a:关闭除指定session外其他session
  • tmux kill-server:关闭所有session

Tab(Windows)管理

  • tmux new-window [-n <win-name>]:创建新窗口
  • tmux switch-window -t <win-name>:切换到指定窗口
  • tmux rename-window <win-name>:重命名当前窗口

Pane管理

  • tmux split-window [-h]:竖直/水平划分窗口
  • tmux select-pane -U/-D/-L/-R:激活上、下、左、右侧Pane
  • tmux swap-pange -U/-D/-L/-R:当前Pane上、下、左、右 移动

帮助

  • tmux list-key:列出所有绑定键
  • tmux list-command:列出所有命令
  • tmux info:列出当前所有Tmux会话信息
  • tmux source-file <tmux-conf>:重新加载Tmux配置文件

配置

set

  • 默认配置文件为~/.tmux.conf
  • set[-option] [-g] [-a]:session选项

    • 全局、追加标志
      • -g:全局设置
      • -a:追加设置,适合option需要字符串、样式值
    • default-terminal
    • display-time
    • escape-time
    • history-limit
    • base-index
    • pane-base-index
  • setw/set-window-option [-g] [-a]:window选项

    • 全局、追加标志同set[-option]
    • allow-rename
    • mode-keys:快捷键模式,可以设置为vi
    • synchronize-panes
  • set[-option] -s:server选项

StatusBar设置

  • StatusBar主要由5部分组成

    • windows列表
      • windows-status-*:默认windows
      • windows-status-current-*:当前windows
      • windows-status-bell-*:后台有活动windows (需开启支持)
    • 左侧显示区
    • 右侧显示区
    • message显示条:占据整个status bar
    • command输入条:占据整个status bar
  • *-style bg=<color>,fg=<color>,<ATTR>指定样式

    • 颜色可以用名称、colour[0-255]#RGB方式指定
    • 属性包括(前加no表关闭)
      • bright
      • dim
      • underscore
      • blink
      • reverse
      • hidden
      • italics
      • strikethrough
  • *-format:设置格式

    • #{}中变量名称会被替换为相应值,支持alias缩写的变量 可以省略{}
      • host#H
      • host_short#h
      • pane_id#D
      • pane_index#P
      • pane_title#T
      • session_name#S
      • window_flags#F
        • *:当前窗口
        • -:最后打开的窗口
        • z:Zoom窗口
      • window_index#I
      • window_name#W
    • #()会被作为shell命令执行并被替换
      • 命令执行不会阻塞tmux,而是展示最近一次命令执行 结果
      • 刷新频率由status-interval控制
  • 这里介绍2.9之后配置风格

bind

  • bind[-key] [-n] [-r] <key>:key mapping
    • -n:无需prefix
    • -r:此键可能重复
  • unbind <key>:解绑捕获

默认KeyMappings

  • 快捷键前缀缺省为C-b
  • <prefix>::进入命令行
  • 以下快捷键都是缺省值,可以解绑

Session

  • s:列出session,可用于切换
  • $:重命名session
  • d:detach当前session
  • D:detach指定session

Tab/Windows

  • c:创建新tab
  • &:关闭当前tab
  • ,:重命名当前tab
  • .:修改当前tab索引编号
  • w:列出所有tab
  • n/p/l:进入下个/上个/之前操作tab
  • [tab-n]:切换到指定编号窗口
  • f:根据显示内容搜索tab
  • tmux中window相当于tab

Panes

  • %:水平方向创建窗口
  • ":竖直方向创建窗口
  • Up/Down/Left/Right:根据箭头访问切换窗口
  • q:显示窗口编号
  • o:顺时针切换窗口
  • }/{:与下个/上个窗口交换位置
  • space:在预置面板布局中循环切换
    • even-horizontal
    • even-vertical
    • main-horizontal
    • main-vertical
    • tiled
  • !:将当前窗口置于新tab
  • C-o/M-o:顺/逆时针旋转当前窗口,即所有窗口循环前/后 移动一个位次
  • t:在当前窗口显示时间
  • z:最大/恢复当前窗口
  • i:显示当前窗口信息
  • x:关闭当前窗口
  • q:显示当前窗口编号
  • [:进入自由复制模式,VI 模式下快捷键同 VI,且
    • <space>:从光标处开始选择(支持 V 选择行)
    • <enter>:复制选择部分
  • ]:粘贴
  • tmux中pane相当于vim中windows

信息

  • ?:列出所有绑定键

转义序列

C0C1 控制字符集

C0 控制字符集

  • CO 控制字符集码位范围:0x00 - 0x1F

    • ASCII 中定义控制字符标准
    • 码位限定在 1byte 可以表示,避免终端机需要实现状态机处理多字节控制序列
    • 现只有少数控制字符被使用
  • C0 控制字符码位范围之外,还有定义有两个具备控制符特点的字符

    • 0x7Fdelete
    • 0x20space

C1 控制字符集

  • C1 控制字符集码位范围:0x80 - 0x9F

    • 8bits ISO/IEC 8859 ASCII 扩展提出后
      • 考虑到可打印字符的最高比特位去掉之后不应变成控制字符
      • C0 控制字符集作为低位、最高位置 1,得到 C1 控制字符集
    • C1 码位在经常被私有编码方案(Windows-1252Mac Os Roman)用于提供额外的可打印字符
  • ISO/IEC 8859 ASCII 扩展标准中指定

    • 为兼容 7bits 传输,所有 C1 控制字符使用 ESC 开头的 7bits 字符序列表示

标准 C 转义规则

  • 非打印(包括控制)字符可以通过其 ASCII 码位 16 进制、8 进制表示
    • \0[ooo]:八进制数 oo 码位字符
    • \x[hh]:十六进制数 hh 码位字符
      • \x0a:同 \n
  • 针对常用非打印字符,有如下简写方式
    • \\:反斜杠 \
    • \':单引号 '
    • \":双引号 "
    • \aBEL ASCII 响铃
    • \bBS ASCII退格
    • \fFF ASCII 进纸
    • \nLF/NL ASCII 换行,开启新行
    • \rCR ASCII 回车,“指针移至行首”
    • \tTAB ASCII 制表符
    • \vVT 垂直制表符

ANSI Escape Sequences

ANSI:一种 In-band Signaling 的转义序列标准,用于控制终端上 光标位置、颜色、其他选项

  • 在文本中嵌入的 ANSI 转义序列,终端会将 ANSI 转义序列解释为相应指令,而不是普通字符

    • ANSI 转义序列使用 ASCII 中字符传递所有信息
  • ANSI 转义序列有不同长度,但都

    • ASCII 字符 ESC0x1b) 开头
      • 8 进制表示:\033
      • 16 进制表示:\x1b
    • 第二字节则是 0x45 - 0x5FASCIIi @A-Z[\]^_)范围内的字符
  • 标准规定,在 8bits 环境中

    • ANSI 转义序列前两个字节的序列可以合并为 0x80 - 0x9F 范围内的单个字节(即 C1 控制字符)
    • 但在现代设备上,C1 控制字符码位被用于其他目的,一般不被使用
      • UTF-8 编码对 x80 字符本就需要 2bytes
      • Windows-1252 编码将 C1 控制字符码位挪作他用

No-CSI - 非控制序列

序列(省略 ESC 对应 C1 名称 效果
N 0x8E SS2 - Single Shift 2 从替代 G2 字符集中选择字符
O 0x8F SS3 - Single Shift 3 从替代 G3 字符集中选择字符
P 0x90 DCS - Device Control String 控制设备
D 仅换行,不重置光标至行首
E 换行并充值光标至行首,类似LF
H 制表,类似TAB
M 翻转换行,回到上一行
X 0x98 SOS - Start of String 引用由 ST 终止的一串文本参数
^ 0x9E PM - Privacy Message 引用由 ST 终止的以穿文本参数
_ 0x9F APC - Application Program Command 引用由 ST 终止的一串文本参数
c - RIS - Reset to Initial State 类似clear命令
[ 0x9B CSI - Control String Sequence 控制序列导入器,某些终端中也可以使用0x9D
\ 0x9C ST - String Terminator 终止其他控件得字符串
] 0x9D OCS - Operating System Command 启动操作系统使用的控制字符串
%G 选择 UTF8 作为字符集
#8 DEC 屏幕校准测试,使用E填充整个终端

Control Sequence Introducer

控制序列导入器:ESC[ + 若干参数字节 + 若干中间字节 + 一个最终字节

  • 常见序列只是把参数用作一系列分号分隔的数字,如:1;2;3

    • 缺少的数字视为 0
    • 某些序列(CUU)把 0 视为 1,以使缺少参数情况下有意义
  • 一部分字符定义“私有”,方便终端制造商插入私有序列

    • 参数字节 <=>? 的使用:ESC[?25hESC[?251 打开、关闭光标显示
    • 最终字节 0x70 - 0x7F
组成部分 字符范围 ASCII字符
参数字节 0x30~0x3F 0-9:;<=>?
中间字节 0x20~0x2F 、!"#$%&'()*+,-./
最终字节 0x40~0x7E @A-Z[]^_a-z{}~, `

光标移动

序列内容 名称 效果
[n]A/[n]B/[n]C/[n]D CU[UDFB] - Cursor Up/Down/Forward/Back 光标移动[n]格,在屏幕边缘则无效
[n]E/[n]F Cursor Next Line/Previous Line 光标移动至下[n]行/上[n]行开头
[n]G Cursor Horizontal Absolute 光标移动到第[n]
[n;m]H CUP - Cursor Position 光标绝对位置
[n;m]f Horizontal Vertical Position CUP
[n]J Erase in Display 清除屏幕部分区域:0 - 光标至末尾;1 - 开头至光标;2 - 整个屏幕
[n]K Erase in Line 清除行内部分区域
[n]S Scroll Up 整页向上滚动 [n]
[n]T Scroll Down 整页向下滚动 [n]
s Save Cursor Position 保存光标当前位置
u Restore Cursor Position 恢复光标位置

窗口

序列内容 名称 效果
5i - 打开辅助端口,通常用于本地串行打印机
4i - 关闭辅助端口,通常用于本地串行打印机
6n Device Status Report ESC[n;m]R 报告光标位置

Select Graphic Rendition

  • SGR 选择图形再现:ESC[[n]m
    • [n]:多个参数用 ; 分隔,缺省为 0
    • m:结束字节
样式
设置值 显示效果 取消值
0 所有属性值重置为默认值,用于取消对后续输出影响
1 高亮或粗体 22
2 半亮 22
4 下划线 24
5 闪烁 25
7 反显,前景、背景色交换 27
8 隐藏,前景、背景色相同,可能不支持 28
9 删除线 29
53 上划线 55
11-19 选择替代字体
3/4位色
前景色值 背景色值 颜色 高亮前景色值 高亮背景色值
30 40 黑色 90 100
31 41 红色 91 101
32 42 绿色 92 102
33 43 黄色 93 103
34 44 蓝色 94 104
35 45 紫红色 95 105
36 46 青蓝色 96 106
37 47 白色 97 107
38 48 控制使用256位、RGB色
39 49 默认颜色

ansi_sgr_colors_16

  • 可通过反显 7 实现背景色、高亮 1 实现多高亮色
8bits 色
  • 8bits 色设置格式
    • ESC[38;5;37m:设置256位前景色
    • ESC[48;5;37m:设置256位背景色
  • 预定义 8bits 色情况
    • 0-7:标准颜色,同 ESC[30-37m
    • 8-15:高强度颜色,同 ESC[90-97m
    • 16-23116 + 36*r + 6*g + b($0 leq r,g,b leq 5$ 得到 6 6 6 立方)
    • 232-255:24阶灰阶

ansi_sgr_colors_256

24bits 色
  • 24bits 色设置格式

    • ESC[38;2;<r>;<g>;<b>m:选择 RGB 前景色
    • ESC[48;2;<r>;<g>;<b>m:选择 RGB 辈景色
  • 字符内容体系结构有一个不太受支持的替代版本

    • ESC[38:2:<Color-Space-ID>:<r>:<g>:<b>:<unused>:<CS tolerance>:<Color-Space: 0="CIELUV";1="CIELAB">m:选择 RGB 前景色
    • ESC[48:2:<Color-Space-ID>:<r>:<g>:<b>:<unused>:<CS tolerance>:<Color-Space: 0="CIELUV";1="CIELAB">m:选择 RGB 背景色
  • 支持 libvte 的终端上支持 ISO-8613-3 的 24bits 前景色、背景色设置,如 XtermKonsole
  • 24bits 色的替代版本是 ISO/IEC 8613-6 采用的 ITUT.416 信息技术

Windows Linux Subsystem

说明

WSL是一个兼容层,类似反过来的Wine,但更底层

  • Linux、Windows程序不兼容,是因为二者内核提供的接口不同

    • ls/dir命令
      • 在Linux下调用getdents内核调用
      • 在Windows下调用NtQueryDirectoryFile内核调用
  • WSL提供Linux内核接口,并转换为NT内核接口

    • 在WSL中执行ls仍然调用getdents
    • WSL收到请求,将系统调用转换为NT内核接口 NTQueryDirectoryFile
    • NT内核收到WSL请求,返回执行结果
    • WSL将结果包装后返回
  • 毕相较于真正Linux系统仍然有不足

    • Docker等涉及未实现的内核特性软件如法使用
    • Raw socket相关相关操作容易出错
    • I/O性能相对孱弱

Cygwin对比

wsl_architecture

  • Cygwin提供了完整的POSIX系统调用API(以运行库 Cygwin*.dll形式提供,但是仍然工作在User Mode

    • Cygwin将POSIX系统调用转换为Win32 API(因为其架设在 Win32子系统上),很多内核操作(如:fork)受限于 Win32实现

    • Linux应用程序必须链接到Cynwin*.dll,需要修改源码 重新编译后才能执行,这样应用程序才不会直接请求内核, 而是调用Cygwin运行库,且编译出的可执行文件为 Win32 PE格式封装,只能在Windows下执行

  • WSL中Linux应用程序进程被包裹在Pico Process中,其发出的 所有系统调用会被直接送往Kernel Mode中的 lxcore.syslxss.sys

    • WSL将POSIX系统调用转换为更底层的NP API调用(WSL和 Win32平行,直接架设在NT内核上)

    • 可以直接执行ELF格式封装的Linux可执行程序

启用

  • 控制面板 ->
  • 程序和功能 ->
  • 启用或关闭windows功能 ->
  • 适用于Linux的Windows子系统

其他

使用

进入WSL

除在图形界面中点击图标,以默认参数启动,还可以在terminal (cmd/powershell等)自定义进入WSL参数

  • wsl.exe:打开默认发行版中默认shell
  • distroname.exe:打开指定发行版中默认shell
  • bash.exe:打开默认发行版中bash shell
  • 这些应用程序默认在path中,可以直接执行

版本管理

  • wslconfig.exe可以用于管理多个子系统的发行版

WSL、Windows互操作

文件

  • Windows所有盘符挂载在WSL中/mnt目录下

  • WSL中所有数据存放在%HOME%/AppData/Local/Packages/{linux发行包名}/LocalState/rootfs

    • 不要在Windows下直接修改,造成权限错误

命令

  • 在cmd中直接调用WSL命令
    1
    2
    PS> wsl [-e] ls -al
    // wsl带参数执行
  • 在WSL中调用Windows命令行程序(在$PATH中)

    1
    2
    $ which ipconfig.exe
    $ ipconfig.exe
  • 在WSL中启动Windows应用(在$PATH中)

    1
    $ notepad.exe
  • 通过pipes通信

    1
    2
    $ cat foo.txt | clip.exe
    PS> ipconfig | wsl grep IPv4

端口、环境变量

  • WSL与Windows共享端口(NT内核?)
  • WSL继承Windows的部分环境变量,如:PATH

Terminal推荐

  • wsl-terminal: 专为WSL开发的终端模拟器,基于minttywslbridge,稳定 易用

  • ConEmu:老牌终端模拟器, 功能强大

  • Hyper:基于Electron的跨平台 终端模拟器

WSL-Terminal

  • WSL-Terminal中包含一些快捷工具

    • tools目录中包含一些脚本,可以通过wscripts.exe 执行修改注册列表,添加一些功能
      • 添加WSL中vim、emacs等打开到右键菜单
      • 添加在WSL中打开文件夹到右键菜单
    • run-wsl-file.exe可以用于在快捷执行wsl脚本,只需要 将其选择为文件打开方式
    • vim.exe可以用WSL中vim打开任何文件,当然一般是配合 tools/中脚本在右键注册后使用
  • 配置

    • 配置文件etc/wsl-terminal.conf
    • 主题文件etc/themes/
    • mintty配置文件etc/mintty

其他问题

文件权限问题

  • 在WSL中,windows实现了两种文件系统用于支持不同使用场景

VolFs

VolFs:着力于在windows文件系统上提供完整的linux文件系统特性 ,通过各种手段实现了对InodesDirectory EntriesFile ObjectsFile DescriptorsSpecial File Types 的支持

  • 为支持Inodes,VolFS会把文件权限等信息保存在 NTFS Extended Attributes

    • 在Windows中新建的文件缺少此扩展参数,有些编辑器也会 在保存文件是去掉这些附加参数
    • 所以不要在Windows中修改WSL文件,否则VolFs无法正确 获得文件metadata
  • WSL中/就是VolFs文件系统

DrvFs

DrvFs:着力提供于Windows系统的互操作性,从Windows的文件权限 (即文件->属性->安全选项卡中的权限)推断出文件对应Linux权限

  • 所有windows盘符挂在在WSL中/mnt是都使用DrvFs文件系统

  • 由于DrvFs文件权限继承机制很微妙,结果就是所有文件权限 都是0777

    • 所以ls结果都是绿色的
    • 早期DrvFs不支持metadata,在Build 17063之后支持 文件写入metadata,但是需要重新挂载磁盘
  • 可以通过设置DrvFs metadata设置默认文件权限

    1
    2
    3
    4
    5
    $ sudo umount /mnt/e
    $ sudo mount -t drvfs E: /mnt/e -o metadata
    // 此时虽然支持文件权限修改,但默认权限仍然是*0777*
    $ sudo mount -t drvfs E: /mnt/e -o metadata,uid=1000,gid=1000,umask=22,fmask=111
    // 此时磁盘中默认文件权限为*0644*
  • 更合适的方式是通过/etc/wsl.conf配置DrvFs自动挂载属性

AutoMatically Configuring WSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 # `/etc/wsl.conf`
[automount]
# 是否自动挂载
enabled = true
# 是否处理`/etc/fstab`文件
mountFsTab = true
# 挂载路径
root = /mnt/
# DrvFs挂载选项,若需要针对不同drive配置,建议使用`/etc/fstab`
options = "metadata,umask=023,dmask=022,fmask=001"
[network]
generateHosts = true
generateResolvConf = true
[interop]
# 是否允许WSL载入windows进程
enabled = true
appendWindowsPath = true
  • 如果需要给不同盘符设置不同挂载参数,需要修改 /etc/fstab

    1
    E: /mnt/e drvfs rw,relatime,uid=1000,gid=1000,metadata,umask=22,fmask=111 0 0