https://distrochooser.de/zh-hans
发行版
Debian -> Ubuntu 前者是最早的社区发行版,后者是前者的迭代 包管理是 APT
CentOS 是 Red Hat 基于 RHEL 的免费版,不带商业支持。包管理是 rpm
2024 年 6 月 30 日停止维护 CentOS 7,届时 CentOS 全系列版本将停止维护
CentOS Stream 作为 CentOS 项目新的成员,旨在滚动更新版
Shell Bash Terminal
Terminal:终端相当于一个程序,一个窗口。比如 Win11 的那个新终端,它只是一个 Terminal,给用户操作。
Shell:是用户键入的命令的解释器,本身并不具体指代哪一种(直译:壳,包裹在操作系统内核 Kernel 的外面)
Cmd、PowerShell:Windows 上的两个 Shell
Bash:Linux 下最常见的 Shell,也就是 Shell 的具体实现,是 POSIX 标准的事实实现
Zsh:另一个 Unix 上的 Shell,高度兼容 Bash。MacOS 切换到 Zsh 上,使得越来越多的人用这个 Shell,很多发行版默认是 Bash,但是也给你安装了 Zsh。
Fish:不兼容 Bash 语法,但默认就提供语法高亮
Git Bash:Git for Windows,用 MSYS2 还是什么的,做了一个模拟兼容层,模拟 bash。所以它本事是一个 Shell
tty
teletypewriter 电传打字机
tty 是一种 字符设备,位于/dev/tty
你在 shell 里输入命令,路径是:键盘->tty->shell->程序->tty->显示
tty 承接了 stdin 和 stdout、stderr
tty 命令可以查看当前处于哪个 tty
/dev/tty1 这种是 内核提供的 虚拟控制台
/dev/pts/0 是 伪终端 pseudo terminal,比如 SSH 登录后一般是这样的,或者 Ghostty 里的(mac 上是叫做 /dev/ttys003)
伪终端,就是它不对应一台真实的硬件终端
真实终端,背后应该是接入键盘、显示器,通过串口连接。
伪终端里面有一对设备,PTY master 端 ←→ PTY slave 端
master 端:给终端模拟器、SSH、tmux 这类软件用
slave 端:给 shell、vim、top、yazi 这类程序用
另一端不是硬件,而是一个软件
Windows 对标 tty 的东西是 conhost.exe,后来也引入 ConPTY 现代模型
包管理器
| 发行版 | 包管理器 | 包后缀 |
|---|---|---|
| Debian/Ubuntu/Mint | apt(现代)/apt-get(传统) | .deb |
| RHEL/Fedora/CentOS(已停止维护) | dnf(现代)/yum(传统) | .rpm |
| Arch/Manjaro | Pacman | .pkg.tar.zst |
| openSUSE | Zypper | .rpm |
网络
netstat、ss 这个对于我来说,就是端口管理工具
ss 更现代一些,我这个 openSUSE 甚至没有 netstat,只有 ss
netstat 在 Windows 上也有,只不过命令的输出不太一致(不像 curl 那样是跨平台的)
其实还有一个叫做 lsof 的命令,用于列出打开的文件(一切皆文件的话,端口也是文件)
lsof -i :80
防火墙
iptables Linux 内核里的防火墙,但是用起来麻烦。在老的发行版上,就是内核;在新的发行版上,内核是 nftables,iptables 则是一个假命令,兼容层,转给其它命令处理
一般来说,你就是用两个命令来管 ufw firewall-cmd
Ubuntu/Debian (UFW)
RHEL/CentOS/Fedora (FirewallD),firewalld 的 d 是 deamon,就是后台服务,管理的工具则是 firewall-cmd
反正先用看服务是否已经跑起来,然后 ss 看是否监听端口,最后用 ufw 打开端口
ss -tlnp | grep :22
firewall-cmd --list-ports
firewall-cmd --add-service=ssh --permanent
firewall-cmd --zone=public --add-port=22/tcp --permanent
firewall-cmd --reload
查看 ip
ip addr show
ip route show
应对有时候没有 ifconfig、route
systemd
现代 Linux 系统的“第一个进程”(PID 1)
功能:系统初始化、服务管理 (nginx)、挂载文件系统、网络配置
systemctl 是 systemd 的控制工具
现在基本上我这种小白能说的上来的 Linux 都有 systemd,我基本就是用来让某个程序开机自启
从 SysVinit 转向 systemd 是最具争议的决策,它管理的事情太多,不符合“做一件事并且做好”的原则,并且二进制日志不符合一切解文本的理念
systemctl enable xxx 多数时候相当于设置这些的单元为开机自启动(但不会立即启动) systemctl disable xxxsystemctl is-enabled xxx 返回 0 是有开机自启(但不一定当前就在工作) systemctl status xxx 现在是否在跑 systemctl start xxx 跑起
虽然它是第一个进程,但是不只有一个,你可以用 ps -ef | grep systemd,检测一下到底有几个 systemd
用户级的 systemd 的 PID 肯定不是 1
PM2 是 nodejs 下类似于 systemd 的工具,用于管理那些前后端服务,你的工具基于 node 的话可以考虑
在 macOS 上,systemctl 被替换为 launchctl
变量
在 SHELL 中
定义变量:
MYVAR=a右值的字符串可以用单引号,也可以用双引号,也可以不用引号
变量名建议大写,等号左右建议无空格
使用变量:
$MYVAR
${MYVAR}这个事情,一般是编写 .sh 的时候,才用,它属于是只在当前 Shell 会话中有效的变量
环境变量
那么环境变量也是一种变量
通过 export 命令标记,并可以传递给子进程
查看环境变量(应该说,PATH 是其中一个环境变量)
echo $PATHLinux 环境变量分为:
永久的:需要用户修改相关的配置文件,变量永久生效
临时的:利用 export 命令,在当前终端下声明环境变量,关闭 Shell 终端失效
添加变量的姿势:
PATH=$PATH:(需要添加的环境变量) :用于分割不同路径
PATH=(需要添加的环境变量)将会覆盖之前的变量
env 命令会输出当前所有环境变量,供你查看
比如:SHELL=/bin/bash,~通常扩展为$HOME的值
普通和管理员的 PATH
我现在普通用户的 PATH 是:
~/.nvm/versions/node/v24.14.0/bin
~/.local/share/pnpm
~/bin
/usr/local/bin
/usr/bin
/bin而 root 是:
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin所以一般是用户路径下的东西找不到
文件夹
cd a
cd a/
cd ./a
cd ./a/第一种系统会自己找,第二种明确告诉系统是一个目录,第三种明确在这里找,而不是找环境变量。
cd /a #错误
cd /usr/local实际上 / 是一个路径,/usr/local 是真实存在的。而 / 下没有 a 这个文件夹
AppImage
正常来讲,直接 ./xxx.AppImage 就可以执行
软件产生的数据与 AppImage 分离
我试了一下 Linux 的微信,但是触发风控了,就没登陆
AppImage 是 Linux 内核支持的,mac 上无法使用
配置代理
国外服务器不需要配置
国内服务器 TODO
家用虚拟机/物理机:
我们为了应对没有 GUI 界面的情况,肯定不能用 v2rayN 这种图形化界面工具(而且这玩意安装起来很费劲)
实际上,就是将 Linux 流量转发到 Windows 上,用 v2rayN 代为处理
(1)v2rayN 不需要开启 TUN,因为 TUN 模式总是卡死
(2)v2rayN 需要打开“允许来自局域网连接”
(3)关闭 Windows 防火墙
(4)Linux 那边用 curl/浏览器 测试效果,不要用 ping,ping 永远走不通
(5)有 GUI 一般可以在设置里设置,Linux 的命令用(当前命令行)
export ALL_PROXY="http://192.168.0.3:10808"| > >>
| 连接命令,stdout 做 stdin
> 后面是文件,覆盖/新建
>> 追加
Unix 与 BSD
最开始,是只有 Unix(由 AT&T 公司研发)
上世纪 70 年代,由于反垄断法,它把 Unix 源码给了 加州大学伯克利分校(Berkeley)
伯克利师生为 Unix 添加了很多新功能,比如 vi,之后将这些工具和 Unix 打包,称之为 BSD(Berkeley Software Distribution)
上世纪 80 年代,反垄断失效,Unix 费用暴涨,伯克利师生决定重写,替换收费的 Unix
这导致 AT&T 公司起诉伯克利分校,后续则是和解了
多年以后,4.4BSD-Lite 发布,并开源,这是后续所有 BSD 的祖先
posix
80 年代,Unix 的各种变体(比如当时的 BSD 和 System V)打得不可开交,posix 规定了一些内容
它的目标是:只要你符合 POSIX,你的代码在任何 Unix-like 系统上都能编译运行。
POSIX 规定了 open() 这种函数名,但没规定背后怎么实现。
Linux 桌面版用的是 Glibc,Android 用的是 Bionic。一个针对 Glibc 编译的应用,在 Android 上找不到它需要的“库文件”。
mac
乔布斯离开苹果后,在 NeXT 公司,基于 Mach 的微内核,套了一层 BSD4.3,做了一套系统
后来苹果又收购了 NeXT,将这些东西整理为 Darwin
“Unix”现在是一个注册商标,苹果花了授权费,为 macOS 买了认证,所以其实 macOS 应该是 真·Unix
GNU/Linux
GNU 是先产生的,并且是借鸡生蛋
1983,理查德·斯托曼(RMS)启动了 GNU 项目,他的目标是复刻整个 Unix 系统,它在商业 Unix 上开发 GCC、Emacs 等
然后 1991 年,Linus Torvalds 写了内核,因此就结合了
许可证
BSD 的许可证很松,不管你后续了,所以 macOS 白嫖了它
GPL 很紧,所以很多商业公司会规避
密钥对
建议是在 linux 上生成密钥对,而不是 windows。如果你的 windows 没有密钥,建议生成一次,以便于找到。ssh 文件夹。
.ssh 文件夹是仅有一个,只要使用 OpenSSH 的软件,不管是不是 VSCode 还是各种乱七八糟的软件,都会使用同一个文件夹
(也有另类,是的,说的就是你,XTerminal,存在自己文件夹下)
生成密钥:(在 windows 上也是这个命令)
ssh-keygen -t rsa -b 2048之后会让你选择密钥的保存位置,默认就行了。
(Linux 是在home/user-name/.ssh,windows 是在C:\Users\user-name/.ssh)
Enter file in which to save the key再之后是问你是否需要密码。这个密码是给私钥的,用于加强私钥。即使用了私钥,还需要输入密码。懒人就直接选不需要了。
Enter passphrase (empty for no passphrase):完成后。会建立两个文件
1、id_rsa 这个是私钥(rsa 是一定是用 rsa 算法的,有的时候就叫 keypair.pem)
2、id_rsa.pub 这个是公钥
这个名字到底叫什么,实际上无所谓,叫 fuck 和 fuck.pub 都行,一般多服务器场景下,就用 aliyun aliyun.pub 这种
总之公钥一定是 pub 后缀,私钥一般没后缀
公钥类似于:
ssh-rsa AAAAB3...Va72PZ liuya@liuya-virtual-machine私钥类似于:
-----BEGIN OPENSSH PRIVATE KEY-----
b3Blbn...CAwQFBgc=
-----END OPENSSH PRIVATE KEY-----在多服务器场景下,我们还需要关注 .ssh 下的 config 和 known_hosts(登录过的服务器的指纹,以免总问你)
config 里可以配置不需要输入密码就能登录的服务器,类似于(重复多次)
Host vps 1.1.1.1 # <----- 这里是你自己起的别名,你可以输入 ssh vps 直接连进去,不需要输入用户名
HostName 1.1.1.1
User ubuntu
IdentityFile ~/.ssh/id_ed25519_vps_us
IdentitiesOnly yes # <----- 限制只使用配置文件里的指定的密钥,以免 agent 中加载其它密钥干扰根据 OS 不同 可能需要调整斜杠和反斜杠
即:个人电脑上,.ssh 下面是公钥私钥都有,比如:
~/.ssh/
├── config
├── known_hosts
├── id_ed25519_github
├── id_ed25519_github.pub
├── id_ed25519_gitlab_work
├── id_ed25519_gitlab_work.pub
├── id_ed25519_vps_us
├── id_ed25519_vps_us.pub
├── id_rsa_legacy_nas
└── id_rsa_legacy_nas.pub服务器上,只有公钥,比如:
~/.ssh/
├── authorized_keys # <-----关键
└── known_hosts # 很多时候没有authorized_keys 里存放允许登录这个账号的公钥:(其中注明了算法,公钥,登录者的身份)
ssh-rsa AAAAB3...Va72PZ liuya@liuya-virtual-machine
ssh-rsa AAAAA...BBBBBB a@b这里的每一行,都是你在个人电脑上导出的公钥文件的内容(它也只有一行)
即,服务器的公钥(别人用来登录它),并不是单独存放在多个零散的文件里,而是集中到 authorized_keys 里
建议:通过 ssh-copy-id -i ~/.ssh/mykey.pub user@example.com
上传公钥,这个命令会要求输入密码,然后会自动追加
(只是追加过去了,config 依然没动,需要自己写)
最后问题:
公钥明明是公开的,直接放在服务器上,让个人电脑,自己登录时,去服务器上自己取/下载,不好吗?
这个是因为,公钥是基于私钥生成的,所以服务器上的公钥本质是你通过密码登录后,自己放过去的,所以你本地的那一份肯定先出现。
你要是硬给自己本地那一份删了也没事,也能用,以后私钥还可以继续导出公钥
Windows 做 Server 踩坑
(1)安装:
如果想让 Windows 做服务端,这里坑还比较大
首先,Windows 专业版虽然内置了 ssh,但是没有 sshd,所以你大概率需要先下载它
AI 们都会推荐你 Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
这一步其实总是卡住(不知道是微软服务器问题还是网络问题,另外四个~是微软要求的)
然后你还需要,启动 sshd 服务,设置开机自启动,放行防火墙端口(这些交给 AI 来做,这些 powershell 命令确实记不住)
你只需要确认 Get-Service sshd ,显示已经启动
(2)登录:
ssh yourname@ip 这一步,需要输入密码
如果该 Windows 登陆了微软账号,那么必须是你邮箱的密码(和远程桌面类似)
(3)配置密钥对:
之前,我们的 Windows 电脑只做客户端,所以我们只需要管 C:\Users\yourname\.ssh 下面的文件
但是,如果是个人电脑,一般只有一个微软账号登进去,它一般属于 Admin 组,所以它会去看
C:\ProgramData\ssh 下面的 administrators_authorized_keys,你把你其它客户端上生成的公钥抄过来
备注提一嘴,*nix 上也有两份,是 ~/.ssh/config 和 /etc/ssh/ssh_config,读取顺序是先用户级再 root 级
这时你还是可能会失败,因为这个文件必须设置为,普通用户无法查看或者继承权限
(4)ssh-copy-id 脚本
在 Windows 上,你即便是安装了 sshd,你也没有这个脚本,这意味着你 Windows 做客户端似乎还是得连进去,然后用命令想 *nix 追加公钥
如果 Windows 做服务端,似乎 Windows 没有也没事
(5)哪个 shell?
默认是 cmd,可以通过 ssh user@hostname powershell 来指定是 ps 还是 wsl 之类的。