#108 什么是“企业 Linux”
Linux 2024-09-17我看了阮一峰推荐的内容中有篇文章讲什么是“企业 Linux”(后面会附原文和中文翻译)。
RHEL 名字叫红帽企业 Linux,SLE 也是 SUSE Linux Enterprise 的缩写,我也一直好奇,这个“企业”到底是什么意思?
#107 转载:Linux 命令行:获取上一个命令的参数
Linux 2023-10-24readline 快捷键
readline 是 GNU 的库,实现命令行编辑功能,bash、ftp、python、zsh、mysql 等程序的命令行界面都是使用 readline 实现的,具体实现有 ctrl-r(查找历史命令)、ctrl-p(上一历史命令)、ctrl-a(跳到行首)等。
最重要的还有本次我们所需的 alt+.(dot)、esc+.、meta+. 得到上一命令的最后一个参数。还有更多快捷键可以参考 readline shortcuts。
mac 上没有 alt 和 meta 键,所以我一般使用 esc+. 来获取上一条最后的参数。
shell/bash 历史展开 (history expand)
用 !$ 获取上一命令的最后一个参数。
历史展开由命令、参数、操作符三部分构成,分别表示展开哪一条命令、该命令的哪个参数、对命令的操作。命令展开完成之后才会进入 .bash_history 中,即执行 history 命令不会看到用于历史展开的参数。
本节的所有命令都假设当前 bash 已经有如下的历史:
$ history
1 echo 1 2 3 4 5
2 ls 6 7 8 9 10
3 echo 11 12 13 14 15
4 cat 16 17 18 19 20
5 echo 21 22 23 24 25
- a. 命令(Event Designators),用 ! 开始一个历史展开。
$ !n # 表示第n条命令,如!2表示执行ls 6 7 8 9 10
$ !-n # 表示倒数第n条命令,如!-3表示执行echo 11 12 13 14 15
$ !! # 表示上一条命令,是!-1的快捷方式
$ !string # 表示以string开始的最近的一条命令,如!echo表示echo 21 22 23 24 25
$ !?string? # 表示含有string的最近的一条命令,如!?6?表示cat 16 17 18 19 20
$ ^string1^string2^ # 表示执行上一条命令,并将其中的第一个string1替换为string2,如果string1不存在则替换失败,不会执行命令。
$ !# # 表示当前命令现在已经输入的部分,如echo 1 2 !#会执行echo 1 2 echo 1 2
- b. 参数(Word Designators),命令中选取指定的参数,: 用于分割命令部分与参数部分。
$ !!:0 # 表示上一命令的第0个参数,即命令本身,得到的是echo
$ !2:n # 表示第2个命令的第n个参数,如!2:2得到的是7
$ !!:^ # 表示上一命令第1个参数,可进一步简写为!^,与!!:1同义,得到的是21
$ !!:$ # 表示上一命令的最后一个参数,可进一步简写为!$,得到的是25
$ !!:x-y # 表示第x到第y个参数,-y意为0-y,如!-2:3-4得到的是18 19
$ !!:* # 表示上一命令的参数部分,可进一步简写为!*,如!!:*得到的是21 22 23 24 25
$ !!:n* # 跟!!:n-$同义
$ !!:n- # 意为!!:n-$-1,从第n个参数到倒数第二个参数,如!-2:3-得到的是18 19
通过 bash 历史展开实现创建并 cd 到目录的方式为:
$ mkdir somewhere/dir && cd !#:1 # 其中!#表示本行所有命令"mkdir somewhere/dir && cd”,:1取第一个参数就是目录名
-
c. 操作符(Modifiers),在可选的参数部分之后,用一个或多个 : 操作符加特定字符。
-
h 去除最后的一个文件路径部分,
- 假设上一条命令
echo /tmp/123/456/,则cd !:1:h:h意为cd /tmp/123; - 假设上一条命令
echo /tmp/123/456,则cd !:1:h:h意为cd /tmp
- 假设上一条命令
- t 去除所有的开始的文件路径部分,
- 假设上一条命令为
echo /tmp/123/456/,则cd !:1:t意为cd; - 假设上一条命令为
echo /tmp/123/456,则cd !:1:t意为cd 456
- 假设上一条命令为
- r 去除后缀,
- 假设上一条命令为
echo /tmp/bbs.c,则echo !:1:r意为echo /tmp/bbs
- 假设上一条命令为
- e 得到后缀,
- 假设上一条命令为
echo /tmp/bbs.c,则echo !:1:e意为echo .c
- 假设上一条命令为
- p print 命令而不执行
[g]s/string1/sting2/将命令的 string1 替换为 string2,g 意为全局替换,- 假设上一条命令为
echo 1 2 1,则!:gs/1/3/意为echo 3 2 3。 - 上面的
^string1^string2^相当于!!:s/string1/string2/
- 假设上一条命令为
[g]&意为执行上次替换,g 意为全局替换。- 接上例,假设上一条命令为
echo 123451,则!:&意为echo 323451
- 接上例,假设上一条命令为
使用符号 $ ($_)
在 shell/bash 里 $ 符号表示当前是普通用户(# 是 root),在 sh 脚本或命令行里,$ 开头的表示变量。
# root 用户
[root@localhost iotl] # echo root
# 普通用户
[root@localhost iotl] $ echo hello
以下是一些特殊变量:
$_代表上一个命令的最后一个参数$#参数个数。$0当前 shell 名称(zsh or bash)或脚本的名字。$1传递给该 shell 脚本的第一个参数。$2传递给该 shell 脚本的第二个参数。$@表示所有的独立的参数,将各个参数分别加双引号返回。$*以一对双引号给出参数列表。$$脚本运行的当前进程 ID 号或所在命令的 PID。$?显示最后命令的退出状态,0 表示执行成功,其他表示失败。$!代表最后执行的后台命令的 PID
总结
- 快捷键使用
esc + . - 执行最近的以 xxx 开头的命令
!xxx - 快捷修改上一条命令用三个
^^^(例如^/^/etc^将ls /改为ls /etc) - 重复当前行前面的命令
!# - 灵活的找到前面的参数: 冒号
!!:3、^开始、&结束(可以缩写为!^和!&,注意不是!#) - 重复前面的命令的参数
!#:1 - 实际中更多使用快捷键,比如交换前后字母有
ctrl + t和esc + t,比如交换前后单词(word)有alt + t(别和alt + dot搞混了)
参考链接:
- [1] http://www.gnu.org/software/bash/manual/bashref.html#History-Interaction
- [2] http://stackoverflow.com/questions/4009412/bash-first-argument-of-the-previous-command
- [3] https://www.cnblogs.com/tianyapiaozi/archive/2012/09/21/bash_history_arguments.html
#106 Debian 系统
Linux Debian 2023-06-14Debian 给人的印象就是历史悠久、社区文化、稳定。
但实际上我还是主要使用的 CentOS 作为服务器操作系统(桌面使用 Ubuntu 很久了,可能从某种程度上认为是 Debian 系统)。
了解一下这个对我来说熟悉又陌生的 Linux 发行版。
- 稳定版提供至少 5 年长期支持(LTS)
- 分支
- 稳定版(stable)
- 测试版(testing)
- 不稳定版本(unstable)
PS:Ubuntu 就是基于 Debian 不稳定版本构建
发行版目录
https://www.debian.org/releases/index.zh-cn.html
| 版本号 | 代号 | 发布日期 | 支持截止日期 | LTS 支持截止日期 | ELTS 支持截止日期 | 当前状态 |
|---|---|---|---|---|---|---|
| 14 | Forky | 待定 | 待定 | 待定 | 待定 | 代号已公布 |
| 13 | Trixie | 待定 | 待定 | 待定 | 待定 | 测试版(testing) — 发布日期尚未确定 |
| 12 | Bookworm | 2023-06-10 | 2026-06-10 | 2028-06-30 | 2033-06-30 | 当前稳定(stable)版本 |
| 11 | Bullseye | 2021-08-14 | 2024-08-14 | 2026-08-31 | 2031-06-30 | 当前旧的稳定(oldstable)版本 |
| 10 | Buster | 2019-07-06 | 2022-09-10 | 2024-06-30 | 2029-06-30 | 已存档版本,另有第三方付费扩展长期支持 |
| 9 | Stretch | 2017-06-17 | 2020-07-18 | 2022-07-01 | 2027-06-30 | 已存档版本,另有第三方付费扩展长期支持 |
| 8 | Jessie | 2015-04-25 | 2018-06-17 | 2020-06-30 | 2025-06-30 | 已存档版本,另有第三方付费扩展长期支持 |
重要组件(以 Debian 14 为例)
| 类型 | 组件 | 说明 |
|---|---|---|
| 初始化系统 | systemd | 提供系统和服务管理功能,作为 Debian 默认的初始化系统,用于启动和管理系统服务。 |
| 默认桌面 | GNOME 44 | - |
| 显示服务器 | Wayland | Wayland 是现代显示服务器协议,提供更高效和安全的显示支持。 |
| 网络管理工具 | NetworkManager | 提供图形化和命令行工具,用于管理有线、无线网络连接,支持 VPN 配置。 |
| 防火墙框架 | nftables | 和其他主流 Linux 发行版一样使用 nftables 取代传统的 iptables。 |
| Python 版本 | Python 3.12 | Python 2 已被废弃。 |
| Shell | Bash 5.x | - |
如果需要添加更多组件或者特定场景(如开发环境、服务器环境),可以进一步补充。
参考资料与拓展阅读
- https://packages.debian.org/stable/
- https://packages.debian.org/stable/gnome/
-
https://packages.debian.org/stable/python/
-
https://www.debian.org/News/2021/
-
https://www.oschina.net/p/debian_linux
-
https://www.debian.org/doc/packaging-manuals/
-
https://www.debian.org/doc/packaging-manuals/menu.html/
-
https://www.debian.org/releases/index.zh-cn.html
- https://wiki.debian.org/LTS
- https://wiki.debian.org/DebianReleases
#105 inode 使用率太高的问题
Linux 2023-04-03Jenkins 发布失败,日志显示 scp No space left on device,也就是磁盘空间不足。
查看之后发现是磁盘占用其实不高,不过 inode 使用率满了(其实监控也在报),也就是说小文件太多了。
[staff001@192.168.64.234 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 29G 8.7G 77% /
tmpfs 972M 0 972M 0% /dev/shm
/dev/vdb 99G 41G 54G 44% /data
[staff001@192.168.64.234 ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/vda1 2621440 2621440 0 100% /
tmpfs 248685 1 248684 1% /dev/shm
/dev/vdb 6553600 467525 6086075 8% /data
通过经验和 find 命令找到文件太多的目录:
find /var -xdev -printf '%h\n' | sort | uniq -c | sort -n | awk '{sum+=$1;print $0;}END{print "\nTotal: "sum}'
# 只看二级目录的数据
find /var -xdev -type f | cut -d / -f 3 | sort | uniq -c | sort -n | awk '{sum+=$1;print $0;}END{print "\nTotal: "sum}'
#104 Linux 网络:开放端口范围
LinuxNetwork Linux 2023-03-03线上环境,有一个服务启动时,四个进程只成功了三个,检查发现端口被占用。
再一看,是被另外三个进程中的一个连接 MongoDB 占用了。
# 查看
cat /proc/sys/net/ipv4/ip_local_port_range
1024 65000
$ sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 1024 65000
PS:查了一下,个人机器(Ubuntu)上配置的是:32768 60999
把下限往上提到 20000,避开服务常用接口:
# 临时配置
echo "20000 65000" > /proc/sys/net/ipv4/ip_local_port_range
sysctl -w net.ipv4.ip_local_port_range="20000 65000"
# 持久配置
vim /etc/sysctl.conf
#103 dd 替代品
Linux 2022-12-25dd if=image.iso of=/dev/sdb bs=4M
# 用 cat 就行:
cat image.iso >/dev/sdb
# 如果想要进度信息:
cat image.iso | pv >/dev/sdb
dd if=/dev/zero of=image.iso bs=4MB count=25
# 用 head:
head -c 100MB /dev/zero >image.iso
#102 bash 上下键搜索历史记录
Linux Bash 2022-12-16我一直用 zsh + omz,但是毕竟 bash 才是大多数情况下的默认 Shell。
zsh 和 bash 都是用上下键来搜索历史记录,但是不同的是,zsh 会利用已经输入部分做前缀匹配,而 bash 不会,只是简单的上一条、下一条。
今天学会一个方法(Bash history search, partial + up-arrow):
bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'
凑活凑活吧。
已经加到我个人的 bash 配置中。
#101 转载:Linux/UNIX 编程如何保证文件落盘
Linux 2022-11-10我们编写程序 write 数据到文件中时,其实数据不会立马写入磁盘,而是会经过层层缓存。每层缓存都有自己的刷新时机,每层缓存都刷新后才会写入磁盘。这些缓存的存在是为了加速读写操作,因为如果每次读写都对应真实磁盘操作,那么读写的效率会大大降低。带来的坏处是如果期间发生掉电或者别的故障,还未写入磁盘的数据就丢失了。对于数据安全敏感的应用,比如数据库,比如交易程序,这是无法忍受的。所以操作系统提供了保证文件落盘的机制。我们来看下这些机制的原理和使用。
#100 关于 Linux 发行版
Linux 操作系统 2022-08-28发行版
- Minix
- Unix 阵营
- 闭源
- HP-UX
- Solaris
- AIX
- macOS
- 开源
- FreeBSD
- NetBSD
- OpenBSD
- DragonFly BSD
- Linux 阵营
- Android (AOSP)
- LineageOS
- Debian
- Ubuntu
- RedHat
- CentOS
- OpenSUSE
- Gentoo
- Arch Linux
- Manjaro
Debian / Ubuntu 和 RHEL / CentOS 衍生版本太多,就不列了。
我们常见的 Linux 发行版应该差不多都能找到自己的位置。
桌面环境
图形库主要就是两种:GTK,Qt
- 基于 GTK
- GNOME
- Xfce
- Cinnamon
- MATE
- LXDE
- Unity:ubuntu
- Budgie
- 基于 Qt
- KDE Plasma
- LXQt
- Deepin Desktop Environment (DDE)
- UKUI:ubunty kylin
个人看法
- 在国际关系越来越趋于对抗的这个局面下,Linux 对于中俄等国都有战略安全的重要作用。
- 国产 Linux 系统厂商大有搞头。
- 关于国产系统:
- 国产 Linux 桌面只有 Deepin 可以一战,而且做了太多工作,应该得到尊敬。
- 国产服务器系统我一个都没有用过,不知道如何。
- Unix 系统的生态和 Linux 完全不是同一个级别。
- 除非有特别的原因,否则应该直接选择 Linux。
- Deepin 等国产 Linux 系统提供商想搞什么国产根系统,想切断和社区的关联,在我看来是非常愚蠢的。
- 反而应该加大对社区的投入。
- 如果不知道该选哪个 Linux 发行版,我的建议是 Ubuntu。
- 无论是服务器还是个人使用,都可以直接选择上一个版本 Ubuntu LTS
- 如果比较喜欢尝鲜,个人使用可以选最新版本 Ubuntu
- 如果对 Ubuntu snap 不满意,就选择 Debian。
- 如果问选哪个桌面环境,就选 GNOME
- KDE 我没有用过,不知道
- 选 GNOME 作为默认桌面的多,应该是有道理的
- 桌面并没有那么重要,方便快捷的命令行操作才是 Linux 精髓
- 如果对发行版不满,就在基准系统上通过增删组件达成自己的目的,不要觉得换一个系统就能完美解决问题。
- 如果有时间折腾不同的发行版,还不如去玩一会儿游戏。