戴老师的博客 - linux
type: channel
link: https://1diff.fun/tag/linux/
items: >&/dev/null
items: iptables入门指南
items: 一条语句查看web日志排名前十的IP/URL页面及总数
items: NC(netcat)使用指南
items: Systemd 入门教程：命令篇
items: LINUX常用命令（基础）
items: Linux 的启动流程
items: Linux Bash Shell中的单引号和双引号
items: rsync 用法教程
items: Systemd 入门教程：实战篇

>&/dev/null
type: item
date: 2026-03-30T09:40:42+00:00
description: Linux/Unix 中的标准输出与错误输出在 Linux/Unix 系统中，屏幕上显示的信息通常来源于 stdout（Standard Output，标准输出）或者 stderr（Standard Error，标准错误输出）。许多人会问：output 就是 output，直接送到屏幕上不就行了，为什么要分成 stdout 和 stderr 呢？这是因为在服务器工作环境下，几乎所有的程序都是运行在后台（background）的。为了方便调试（debug），一般在设计程序时，会将正常的 stdout 送到一个文件，而将错误的信息 stderr 存到不同的文件中。正常的 output：例如程序开始运行的时间、当前在线人数等。错误的 output：例如无法找到用户想要访问的 URL，或者信用卡认证失败等。什么是 /dev/null有了上述认知后，我们再来看什么是 > /dev/null。这条命令的意思是将 stdout 送到 /dev/null 里面。那么，什么是 /dev/null 呢？/dev/null 是 Unix/Linux 里的「无底洞」。任何 output 送去了「无底洞」就再也无法找回了。相信我，数据真的消失了！那么，在什么情况下要把 output 送去这个无底洞呢？这里没有标准答案，但通常来说，如果你不想看到 output，或者 output 太多太大，有可能把硬盘占满的时候，程序设计就会考虑将 output 送到 /dev/null。重定向语法详解：>/dev/null 2>&1在 Shell 脚本中，经常能看到 >/dev/null 2>&1 这样的写法。这条命令的意思是将标准输出和错误输出全部重定向到 /dev/null 中，也就是将产生的所有信息丢弃。命令的结果可以通过 %> 的形式来定义输出。我们可以将这个组合 >/dev/null 2>&1 分解为五个部分来理解：>：代表重定向到哪里。例如：echo "123" > /home/123.txt。/dev/null：代表空设备文件。2>：表示 stderr（标准错误）。&：表示等同于的意思。2>&1 表示 2 的输出重定向等同于 1。1：表示 stdout（标准输出）。系统默认值是 1，所以 >/dev/null 等同于 1>/dev/null。因此，>/dev/null 2>&1 也可以写成 1>/dev/null 2>&1。执行过程解析上述语句的执行过程如下：1>/dev/null：首先表示标准输出重定向到空设备文件，也就是不输出任何信息到终端，说白了就是不显示任何信息。2>&1：接着，标准错误输出重定向到标准输出。因为之前标准输出已经重定向到了空设备文件，所以标准错误输出也随之重定向到空设备文件。command > file 2>file 与 command > file 2>&1 的区别下面就为大家说明一下，command > file 2>file 与 command > file 2>&1 有什么不同的地方。command > file 2>file意思是将命令所产生的标准输出信息，和错误的输出信息送到 file 中。这样的写法，stdout 和 stderr 都直接送到 file 中，file 会被打开两次。这样 stdout 和 stderr 会互相覆盖，相当使用了 FD1 和 FD2 两个文件描述符同时去抢占 file 的管道。command > file 2>&1这条命令将 stdout 直接送向 file，stderr 继承了 FD1 管道后，再被送往 file。此时，file 只被打开了一次，也只使用了一个管道 FD1，它包括了 stdout 和 stderr 的内容。从 I/O 效率上来看，前一条命令的效率要比后一条命令的效率低。所以在编写 Shell 脚本的时候，较多的时候我们会用 command > file 2>&1 这样的写法。说明：本文所述重定向语法适用于大多数 Bourne Again Shell (Bash) 及兼容的 POSIX Shell 环境。

iptables入门指南
type: item
date: 2026-03-30T09:40:15+00:00
description: 1. iptables 防火墙简介Netfilter/iptables（以下简称 iptables）是 Unix/Linux 系统自带的优秀且完全免费的基于包过滤的防火墙工具。它的功能十分强大、使用非常灵活，可以对流入、流出及流经服务器的数据包进行精细的控制。特别是它可以在低配置环境下运行良好，提供数百台机器的办公上网共享服务丝毫不逊色于数万的企业级专业路由器防火墙。iptables 是 Linux 2.4 及 2.6 内核中集成的服务，其功能与安全性比老一辈的 ipfwadm、ipchains 强大得多。一般认为 iptables 工作在 OSI 七层模型的第二层、第三层和第四层。2. iptables 名词和术语不少刚接触到 iptables 的初学者会被相关名词搞得很晕，不知道其所云的具体意思。本章不会像某些书籍一样长篇大论，而是以最基本的概念让大家容易理解。2.1 什么是容器容器就是装东西的（如箱、包、坛等），用来包装或转载物品的存寄器。在 iptables 里，就是用来描述这种包含或者说术语的关系。下面我们就来说说这些包含关系。2.2 什么是 Netfilter/iptablesNetfilter 是表（tables）的容器。这样解释大家肯定还晕，举例来说：如果把 Netfilter 看成某小区的一栋大楼，那么表（tables）就是楼里的其中一套房子。这套房子（tables）就属于这栋楼"Netfilter"。比如，把你们家所在的小区所在楼当成 Netfilter。2.3 什么是表（tables）表（tables）是链的容器，及所有的链（chains）都是属于表（tables）。如上，如果把 Netfilter 看成某个小区的一栋楼，那么表（tables）就是楼里的某一套房子，比如你们家住的房子。当然了，表（tables）可能不止一个！2.4 什么是链（chains）链（chains）是规则（Rules）的容器，链属于表。接上，如果表（tables）当做一套房子，那么链（chains）可以说是房子里的家具（桌子、柜子等）。每一套房子都可能会有桌子柜子等。2.5 什么是规则（Policy/Rules）规则（Policy）就比较容易理解了，柜子（Policy）属于链（chains）。就是 iptables 一系列过滤信息和具体操作方法，可以理解为购买什么家具，并且如何摆放，设计得更符合要求等。2.6 术语关系整理描述完了基本术语，我们画个形象的表格帮我们理解记忆：Netfilter/iptables表（tables）链（chains）规则（Policy）小区的一栋楼楼里的房子房子里的柜子增加、摆放的规则3. iptables 工作流程前面的介绍已经提到，iptables 是采取数据包过滤机制工作的，所以它会对请求的数据包的包头数据进行分析，并根据我们预先设定的规则进行匹配，来决定是否可以进入、流出、流经主机。下面我们以 iptables 进入主机进行过滤的流程图为例子：提示：防火墙规则的执行顺序认为从前到后依次执行，遇到匹配的规则就不再继续向下检查。如果遇到不匹配的规则则会继续向下进行。重点： 匹配上了拒绝规则也是匹配，因此不再继续向下进行，这一点大家要注意。例如：同时执行了以下规则[root@Nagios2 ~]# iptables -A INPUT -p tcp --dport 3306 -j DROP [root@Nagios2 ~]# iptables -A INPUT -p tcp --dport 3306 -j ACCEPT此时通过命令 telnet 192.168.132.194 3306 检查 3306 是不通的。原因就是 telnet 请求已匹配上了拒绝规则，因此不会再找下面的允许规则。如果需要 telnet 192.168.132.194 3306 连通，可以把 ACCEPT 规则中的 -A 改为 -I，即为 iptables -I INPUT -p tcp --dport 3306 -j ACCEPT，把允许规则放在 INPUT 链的第一行生效。再来一个流程的图例：此例来自于交换机中 ACL 过滤，如 iptables 流程几乎一模一样。入站数据包流程图：出站数据包：小提示： 对于交换机的 ACL 数据包过滤，除了顺序匹配外，还有深度匹配，即读完所有的再去匹配，匹配最精确的规则。4. iptables 的表（tables）和链（chains）描述完 iptables 术语后，相信大家对 iptables 的表和链有了初步的了解。默认情况下，iptables 根据功能和表的定义划分，最常用的有三个表，分别是 filter、nat、mangle。其中每个表又有各自包含不同的操作链（chains）。小提示…

一条语句查看web日志排名前十的IP/URL页面及总数
type: item
date: 2026-03-30T09:39:46+00:00
description: 一条语句查看 Web 日志排名前十的 IP/URL 页面及总数通过分析 Nginx Web 访问日志，我们可以快速统计访问量前十的 IP 地址以及热门页面地址。这有助于识别网站受欢迎的内容，以及排查高流量 IP 的访问行为（例如是否存在恶意爬虫或攻击）。以下命令基于标准的 Linux shell 工具链（awk、sort、uniq、head），适用于大多数 Nginx/Apache 访问日志分析场景。统计访问量前十的 IP 地址该命令用于提取日志中所有请求的源 IP 地址，统计出现频率并展示排名前十的结果。awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 10执行结果示例： 391942 211.**.151.218 269168 218.**.103.140 142282 112.**.20.133 105460 112.**.25.241 96016 119.**.155.137 89926 112.**.31.16 83113 218.**.200.19 79975 112.**.28.11 79890 119.**.156.14 72041 124.**.110.72统计特定日期的访问 IP 排名如果需要分析某一天的访问情况，可以先通过 grep 过滤日期，再进行统计。请注意，日志中的日期格式需与实际日志文件一致（例如 07/Nov/2013）。grep "07/Nov/2013" access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10执行结果示例： 3452 60.**.235.88 2297 119.**.195.228 2258 113.**.145.91 1221 123.**.187.223 905 211.**.82.175 899 117.**.5.207 888 112.**.24.202 787 110.**.139.183 576 143.**.5.44 574 125.**.18.21统计访问量前十的 URL 页面通过提取日志中的特定字段（通常为 Referer 或请求 URL），可以分析哪些页面最受欢迎。在常见的 Combined 日志格式中，$11 通常对应 Referer 字段（即用户来源页面），具体字段索引需根据实际日志格式调整。awk '{print $11}' access.log | sort | uniq -c | sort -nr | head -n 10执行结果示例：1420617 "http://***.com/forum.php" 844547 "http://***.com/?fromuid=1180" 760045 "http://www.***.com/" 697515 "http://www.***.com/forum.php" 436309 "http://www.***.com/?fromuid=1080" 279609 "http://www.***.com/?fromuid=21" 172784 "http://www.***.com/?fromuid=2123" 108563 "http://www.***.com/?fromuid=1090" 86906 "http://www.***.com/plugin.php?id=sanree_brand:sanree_brand" 80661 "http://www.***.com/plugin.php?id=sanree_brand_goods:sanree_brand_goods"说明命令逻辑修正：在使用 uniq -c 统计次数前，必须先通过 sort 将相同内容排列在一起，否则 uniq 只能统计相邻的重复行。上述命令已确保包含 sort 步骤。日志格式差异：awk '{print $11}' 中的字段索引 $11 取决于 Nginx/Apache 的日志格式配置（log_format）。如果是标准 Combined 格式，$11 通常为 Referer；若需统计请求的 URL 路径，通常对应 $7 或其他字段，建议使用 head -1 access.log 查看字段分布。时效性：文中示例日期（2013 年）较早，实际操作时请替换为当前日志中的日期格式。

NC(netcat)使用指南
type: item
date: 2026-03-30T09:37:21+00:00
description: NC (Netcat) 使用指南第一次知道 nc（Netcat）是好几年前的事了，那个时候天比现在更蓝，草比现在更绿，卤煮也还是一个刚上大学不久的青葱骚年...现在把这个 01 年的老古董拿出来说好像有点炒冷饭的意思，资料也铺天盖地了，说多了还惹人嫌。不过没办法啊，毕竟当卤煮逐渐发现它有许多颇有内涵的功能的时候，连小伙伴都让它给惊呆了 :D ...由于对 Hacker 文化的兴趣，顺理成章的在合适的时候发现了 nc。但当时的卤煮正值被铺天盖地的计算机方方面面知识砸得晕晕乎乎的人生阶段... 对于这个一直享有“瑞士军刀”之名的软件，找过来看了两把完全没有发现其中的滚滚内涵。因为是这样的，nc 提供的基本功能并不多，Windows 版本的 prompt> nc -h 所给出的所谓官方操作文档不过下面这寥寥数语：[v1.11 NT www.vulnwatch.org/netcat/] connect to somewhere: nc [-options] hostname port[s] [p listen for inbound: nc -l -p port [options] [hostname options: -d detach from console, background m -e prog inbound program to exec [dangerou -g gateway source-routing hop point[s], up t -G num source-routing pointer: 4, 8, 12, -h this cruft -i secs delay interval for lines sent, po -l listen mode, for inbound connects -L listen harder, re-listen on socke -n numeric-only IP addresses, no DNS -o file hex dump of traffic -p port local port number -r randomize local and remote ports -s addr local source address -t answer TELNET negotiation -u UDP mode -v verbose [use twice to be more ver -w secs timeout for connects and final ne -z zero-I/O mode [used for scanning] port numbers can be individual or ranges: m-n [inclusive]参数详解-d：字面上大约是后台运行的意思，不占用当前 Shell。-e：这个参数大有内涵。网上一般翻译成程序重定向什么的，但是“重定向”这个词... 卤煮暂时没去看源码，不知道其具体做了什么事情，但猜测可能是 fork 一个子进程 exec 用户程序，然后父进程 wait 子进程的做法。这个 -e 用在 Server 端的时候，目测是在 accept 成功之后，然后把这个用户程序的输入输出重定向到 Client Socket 对应的 readfd 和 writefd 上。具体应用下面再说。-g：额... 这个参数从文档字面上看不太懂（一堆英文专业术语冒出来好可怕... :X)。有些同学翻译成“源路由跳点”实在是太翻译软件了。看下资料大致上是为了做到强制数据流经这些节点，这样就有机会做到类似利用节点 IP 巧妙的避开目标机的 ACL 限制这样的功能。官文用了一个词叫"loose-source-routed path"，loose 猜测意思大约是指仅简单的保证会经过 -g 给的节点，并不能保证以这条列表的所示路径来完成链路的意思，因为路由发包所选择的下一个 hop 是有自己的路由策略的吧，所以保证不了两个路由间的具体路径。各个操作系统的版本不一定都支持 -g，至于数据是否会依照所给节点顺序来传递现在也还不是很清楚。-G：在 -g 所给列表中选择一个地址作为当前的下一个路由。据说是因为 IP 的内存对象都是 4 字节存储，所以 -G 所给参数也得是 4 的倍数，虽然自己换算下也没什么但这种设计只能用惨无人道来形容。这个功能据说在“网络诈骗”方面有一定用武之地，这个卤煮暂时没感受。（CentOS 装了个版本没有 -g 和 -G）-h：For help。-i：每行数据发送出去的延时时间吧（秒）。-l：会 listen 的东东我们都管他叫 Server... 理解成 Server Mode 就好，一次性行为（怎么读都可以...…

Systemd 入门教程：命令篇
type: item
date: 2026-03-30T09:36:53+00:00
description: 编者注：本文为历史博文归档；涉及 JDK、框架与工具链版本请以当前官方文档为准。引用外链图片可能失效，阅读时请注意时效性。Systemd 是 Linux 系统工具，用来启动守护进程，已成为大多数发行版的标准配置。本文介绍它的基本用法，分为上下两篇。今天介绍它的主要命令，下一篇介绍如何用于实战。一、由来历史上，Linux 的启动一直采用 init 进程。下面的命令用来启动服务：$ sudo /etc/init.d/apache2 start # 或者 $ service apache2 start这种方法有两个主要缺点：启动时间长：init 进程是串行启动，只有前一个进程启动完，才会启动下一个进程。启动脚本复杂：init 进程只是执行启动脚本，不管其他事情。脚本需要自己处理各种情况，这往往使得脚本变得很长。二、Systemd 概述Systemd 就是为了解决这些问题而诞生的。它的设计目标是，为系统的启动和管理提供一套完整的解决方案。根据 Linux 惯例，字母 d 是守护进程（daemon）的缩写。Systemd 这个名字的含义，就是它要守护整个系统。（上图为 Systemd 作者 Lennart Poettering）使用了 Systemd，就不需要再用 init 了。Systemd 取代了 initd，成为系统的第一个进程（PID 等于 1），其他进程都是它的子进程。$ systemctl --version上面的命令查看 Systemd 的版本。Systemd 的优点是功能强大，使用方便；缺点是体系庞大，非常复杂。事实上，现在还有很多人反对使用 Systemd，理由就是它过于复杂，与操作系统的其他部分强耦合，违反"keep simple, keep stupid"的 Unix 哲学。（上图为 Systemd 架构图）三、系统管理Systemd 并不是一个命令，而是一组命令，涉及到系统管理的方方面面。3.1 systemctlsystemctl 是 Systemd 的主命令，用于管理系统。# 重启系统 $ sudo systemctl reboot # 关闭系统，切断电源 $ sudo systemctl poweroff # CPU 停止工作 $ sudo systemctl halt # 暂停系统 $ sudo systemctl suspend # 让系统进入冬眠状态 $ sudo systemctl hibernate # 让系统进入交互式休眠状态 $ sudo systemctl hybrid-sleep # 启动进入救援状态（单用户状态） $ sudo systemctl rescue3.2 systemd-analyzesystemd-analyze 命令用于查看启动耗时。# 查看启动耗时 $ systemd-analyze # 查看每个服务的启动耗时 $ systemd-analyze blame # 显示瀑布状的启动过程流 $ systemd-analyze critical-chain # 显示指定服务的启动流 $ systemd-analyze critical-chain atd.service3.3 hostnamectlhostnamectl 命令用于查看当前主机的信息。# 显示当前主机的信息 $ hostnamectl # 设置主机名 $ sudo hostnamectl set-hostname rhel73.4 localectllocalectl 命令用于查看本地化设置。# 查看本地化设置 $ localectl # 设置本地化参数 $ sudo localectl set-locale LANG=en_GB.utf8 $ sudo localectl set-keymap en_GB3.5 timedatectltimedatectl 命令用于查看当前时区设置。# 查看当前时区设置 $ timedatectl # 显示所有可用的时区 $ timedatectl list-timezones # 设置当前时区 $ sudo timedatectl set-timezone America/New_York $ sudo timedatectl set-time YYYY-MM-DD $ sudo timedatectl set-time HH:MM:SS3.6 loginctlloginctl 命令用于查看当前登录的用户。# 列出当前 session $ loginctl list-sessions # 列出当前登录用户 $ loginctl list-users # 列出显示指定用户的信息 $ loginctl show-user ruanyf四、Unit4.1 含义Systemd 可以…

LINUX常用命令（基础）
type: item
date: 2026-03-30T09:34:34+00:00
description: Linux 常用命令（基础）本文整理 Linux 常用基础命令，涵盖日常操作及文末的关机/重启相关命令说明。常用命令1. manman (Manual) 命令用于查看命令的帮助文档，对你熟悉或不熟悉的命令提供帮助解释。示例：man ls查看 ls 相关的用法说明。注： 按 q 键或者 Ctrl+C 退出。在 Linux 下可以使用 Ctrl+C 终止当前程序运行。2. lsls (List) 用于查看目录或者文件的属性，列举出任一目录下面的文件。示例：ls /usr/man ls -l输出说明：首字符表示文件类型：d 表示目录 (directory)，- 表示文件，l 表示连接文件 (link)。后续字符表示文件或者目录许可权限：分别用可读 (r)、可写 (w)、可运行 (x) 表示。3. cpcp (Copy) 用于拷贝文件。示例：cp filename1 filename2 # 把 filename1 拷贝成 filename2 cp 1.c netseek/2.c # 将 1.c 拷到 netseek 目录下命名为 2.c4. rmrm (Remove) 用于删除文件和目录。示例：rm 1.c # 将 1.c 这个文件删除5. mvmv (Move) 用于移走目录或者改文件名。示例：mv filename1 filename2 # 将 filename1 改名为 filename2 mv qib.tgz ../qib.tgz # 移到上一级目录6. cd / pwdcd (Change Directory)：改变当前目录。pwd (Print Working Directory)：查看当前所在目录完整路径。示例：pwd # 查看当前所在目录路径 cd netseek # 进入 netseek 这个目录 cd # 退出当前目录（回到用户主目录）7. cat / more将某个文件的内容显示出来。两个命令的区别在于：cat 把文件内容一直打印出来，而 more 则分屏显示。示例：cat > 1.c # 把代码粘贴到 1.c 文件里，按 Ctrl+D 保存代码 cat 1.c # 查看文件内容 more 1.c # 分屏查看文件内容编译相关：gcc -o 1 1.c # 将 1.c 编译成可执行文件8. chmodchmod (Change Mode) 用于修改文件权限。用法：符号模式：chmod [who][+|-|=][mode] filename数字模式：chmod [八进制数] filename示例：chmod u+x filename # 只想给自己运行，别人只能读 chmod g+x filename # 同组的人来执行参数说明：u 表示文件主人 (user)，g 表示文件所在组 (group)，o 表示其他人 (others)。r 表可读，w 表可写，x 表可以运行。9. clear / dateclear：清屏，相当于 DOS 下的 cls。date：显示当前系统时间。10. mountmount 用于加载一个硬件设备。用法：mount [参数] 要加载的设备 载入点示例：mount /dev/cdrom /mnt/cdrom # 加载光盘设备到挂载点 cd /mnt/cdrom # 进入光盘目录11. susu (Switch User) 用于在不退出登录的情况下，切换到另外一个人的身份。用法：su -l 用户名 # 如果用户名缺省，则切换到 root 状态示例：su -l netseek # 切换到 netseek 这个用户，将提示输入密码12. whoami / whereis / which / idwhoami：确认自己身份。whereis：查询命令所在目录以及帮助文档所在目录。which：查询该命令所在目录 (类似 whereis)。id：打印出自己的 UID 以及 GID。(UID: 用户身份唯一标识。GID: 用户组身份唯一标识。每一个用户只能有一个唯一的 UID 和 GID)示例：whoami # 显示你自己登录的用户名 whereis bin # 显示 bin 所在的目录，例如：/usr/local/bin which bin # 查询 bin 命令的路径13. grep / findgrep：文本内容搜索。find：文件或者目录名以及权限属主等匹配搜索。示例：grep success * # 查找当前目录下面所有文件里面含有 success 字符的文件14. kill可以杀死某个正在进行或者已经是僵尸 (Zombie) 状态的进程。示例：ps ax # 查看进程列表，配合 kill 使用15. passwd可以设置或修改用户口令。16. history查看用户用过的命令历史。示例：hist…

Linux 的启动流程
type: item
date: 2026-03-30T09:34:00+00:00
description: 编者注：本文为历史博文归档；涉及 JDK、框架与工具链版本请以当前官方文档为准。引用外链图片可能失效，阅读时请注意时效性。半年前，我写了《计算机是如何启动的？》，探讨了 BIOS 和主引导记录的作用。那篇文章不涉及操作系统，只与主板的板载程序有关。今天，我想接着往下写，探讨操作系统接管硬件以后发生的事情，也就是操作系统的启动流程。这个部分比较有意思。因为在 BIOS 阶段，计算机的行为基本上被写死了，程序员可以做的事情并不多；但是，一旦进入操作系统，程序员几乎可以定制所有方面。所以，这个部分与程序员的关系更密切。我主要关心的是 Linux 操作系统，它是目前服务器端的主流操作系统。下面的内容针对的是 Debian 发行版，因为我对其他发行版不够熟悉。1. 加载内核操作系统接管硬件以后，首先读入 /boot 目录下的内核文件。以我的电脑为例，/boot 目录下面大概是这样一些文件：$ ls /boot config-3.2.0-3-amd64 config-3.2.0-4-amd64 grub initrd.img-3.2.0-3-amd64 initrd.img-3.2.0-4-amd64 System.map-3.2.0-3-amd64 System.map-3.2.0-4-amd64 vmlinuz-3.2.0-3-amd64 vmlinuz-3.2.0-4-amd642. 启动初始化进程内核文件加载以后，就开始运行第一个程序 /sbin/init，它的作用是初始化系统环境。由于 init 是第一个运行的程序，它的进程编号（PID）就是 1。其他所有进程都从它衍生，都是它的子进程。3. 确定运行级别许多程序需要开机启动。它们在 Windows 叫做"服务"（service），在 Linux 就叫做"守护进程"（daemon）。init 进程的一大任务，就是去运行这些开机启动的程序。但是，不同的场合需要启动不同的程序，比如用作服务器时，需要启动 Apache，用作桌面就不需要。Linux 允许为不同的场合，分配不同的开机启动程序，这就叫做"运行级别"（runlevel）。也就是说，启动时根据"运行级别"，确定要运行哪些程序。Linux 预置七种运行级别（0-6）。一般来说，0 是关机，1 是单用户模式（也就是维护模式），6 是重启。运行级别 2-5，各个发行版不太一样，对于 Debian 来说，都是同样的多用户模式（也就是正常模式）。init 进程首先读取文件 /etc/inittab，它是运行级别的设置文件。如果你打开它，可以看到第一行是这样的：id:2:initdefault:initdefault 的值是 2，表明系统启动时的运行级别为 2。如果需要指定其他级别，可以手动修改这个值。那么，运行级别 2 有些什么程序呢？系统怎么知道每个级别应该加载哪些程序呢？答案是：每个运行级别在 /etc 目录下面，都有一个对应的子目录，指定要加载的程序。/etc/rc0.d /etc/rc1.d /etc/rc2.d /etc/rc3.d /etc/rc4.d /etc/rc5.d /etc/rc6.d上面目录名中的 rc，表示 run command（运行程序），最后的 d 表示 directory（目录）。下面让我们看看 /etc/rc2.d 目录中到底指定了哪些程序。$ ls /etc/rc2.d README S01motd S13rpcbind S14nfs-common S16binfmt-support S16rsyslog S16sudo S17apache2 S18acpid ...可以看到，除了第一个文件 README 以外，其他文件名都是"字母 S + 两位数字 + 程序名"的形式。字母 S 表示 Start，也就是启动的意思（启动脚本的运行参数为 start）；如果这个位置是字母 K，就代表 Kill（关闭），即如果从其他运行级别切换过来，需要关闭的程序（启动脚本的运行参数为 stop）。后面的两位数字表示处理顺序，数字越小越早处理，所以第一个启动的程序是 motd，然后是 rpcbind、nfs......数字相同时，则按照程序名的字母顺序启动，所以 rsyslog 会先于 sudo 启动。这个目录里的所有文件（除了 README），就是启动时要加载的程序。如果想增加或删除某些程序，不建议手动修改 /etc/rcN.d 目录，最好是用一些专门命令进行管理（参考 这里 和 这里）。4. 加载开机启动程序前面提到，七种预设的"运行级别"各自有一个目录，存放需要开机启动的程序。不难想到，如果多个"运行级别"需要启动同一个程序，那么这个程序的启动脚本，就会在每一个目录里都有一个拷贝。这样会造成管理上的困扰：如果要修…

Linux Bash Shell中的单引号和双引号
type: item
date: 2026-03-30T09:33:10+00:00
description: 引言在 Linux Bash Shell 脚本编程中，正确理解单引号与双引号的区别至关重要。它们在处理变量扩展、特殊字符解析以及命令执行等方面遵循不同的规则。合理运用引号不仅能避免常见的语法错误，还能显著提升脚本的稳定性与可读性。一、单引号和双引号的基本区别（一）单引号（' '）严格的字面引用单引号内的所有字符均被视为字面量（Literal）。除了用于结束字符串的单引号本身外，其他特殊字符（如美元符号 $、反引号 ` 、反斜杠 \ 等）都会失去特殊含义。例如，定义变量 var='This is a $variable' 后执行 echo $var，Shell 不会解析 $variable，而是直接输出字符串原貌。代码示例：var='This is a $variable' echo $var输出结果：This is a $variable限制转义字符功能在单引号内部，反斜杠 \ 仅被视为普通字符，无法用于转义。因此，无法直接在单引号内嵌套单引号。若需在单引号字符串中包含单引号，必须采用特殊拼接方式。例如，直接写 echo 'I can't write this' 会导致语法错误，因为 can't 中的引号会提前终止字符串。正确做法是使用 '\'' 序列，其逻辑为：结束前一个单引号、添加一个转义的单引号、开启新的单引号。代码示例：echo 'I can'\''t write this'输出结果：I can't write this（二）双引号（" "）部分特殊字符解释双引号允许部分特殊字符保留其功能，主要包括变量扩展（$）、命令替换（ ` 或 $()）以及转义字符（\）。其余特殊字符则被视为字面量。变量会被其值替换，命令替换也会正常执行。代码示例：num=5 echo "The value of num is $num"输出结果：The value of num is 5防止单词分割双引号内的内容会被视为一个整体单元。即使字符串中包含空格或制表符，Shell 也不会对其进行单词分割（Word Splitting）。例如，variable="a variable with spaces"，使用 echo "This is $variable" 会将整个字符串作为一个参数传递；而若不加双引号 echo This is $variable，Shell 可能会将其分割为多个参数。代码示例：variable="a variable with spaces" echo "This is $variable" echo This is $variable输出结果：This is a variable with spaces This is a variable with spaces注意：虽然上述示例输出看起来相同，但在作为命令参数传递时（如传递给 rm 或 cp），是否加双引号会导致参数个数的本质区别。（三）使用场景对比不需要变量替换和命令替换时优先使用单引号。这能确保字符串的字面意义，避免 Shell 意外解析其中的特殊字符。适用于处理固定的文件路径、命令选项或正则表达式等场景。代码示例：echo 'The file is located at /home/user/documents/file.txt'输出结果：The file is located at /home/user/documents/file.txt需要变量替换或命令替换时必须使用双引号。在构建动态命令、输出包含变量值的信息等情况下，双引号能正确处理变量扩展和命令替换，同时防止单词分割。代码示例：name="John" echo "Hello, $name"输出结果：Hello, John二、命令替换：反引号与 $()（一）功能介绍反引号（ ` ）反引号内的语句会被当作命令优先执行，其标准输出结果将替换反引号部分，然后再执行整个命令。代码示例：echo `date`输出结果：Wed Aug 23 10:30:00 CST 2023$() 形式功能与反引号完全相同，但这是 POSIX 规范推荐的标准形式，且具有更好的嵌套可读性。代码示例：echo $(date)输出结果：Wed Aug 23 10:30:00 CST 2023（二）使用建议虽然反引号在大多数 Shell 环境中仍能正常工作，但为了遵循 POSIX 规范并提高脚本的兼容性与可维护性，建议始终使用 $() 形式进行命令替换。特别是在需要嵌套命令替换时，$() 的可读性远优于反引号。说明：本文内容基于标准 Bash Shell 行为，适用于大多数 Linux 发行版及 macOS 默认终端。关于命令替换，$() 为 POSIX 标准推荐写法，反引号虽兼容但已视为遗留语法。

rsync 用法教程
type: item
date: 2026-03-30T09:32:56+00:00
description: 一、简介rsync（remote sync）是一个常用的 Linux 应用程序，用于文件同步。它可以在本地计算机与远程计算机之间，或者两个本地目录之间同步文件（但不支持两台远程计算机之间的直接同步）。除了作为同步工具，它也可以当作文件复制工具，替代 cp 和 mv 命令。与其他文件传输工具（如 FTP 或 scp）不同，rsync 的最大特点是增量传输：它会检查发送方和接收方已有的文件，仅传输有变动的部分（默认规则是文件大小或修改时间有变动）。二、安装如果本机或者远程计算机没有安装 rsync，可以使用以下命令进行安装。注意，传输的双方都必须安装 rsync。# Debian/Ubuntu $ sudo apt-get install rsync # Red Hat/CentOS $ sudo yum install rsync # Arch Linux $ sudo pacman -S rsync三、基本用法3.1 -r 参数在本地使用 rsync 命令时，它可以作为 cp 和 mv 命令的替代方法，将源目录同步到目标目录。$ rsync -r source destination上面命令中，-r 表示递归（recursive），即包含子目录。注意，-r 是必须的，否则 rsync 无法处理目录。source 表示源目录，destination 表示目标目录。如果有多个文件或目录需要同步，可以写成下面这样：$ rsync -r source1 source2 destination上面命令中，source1 和 source2 都会被同步到 destination 目录中。3.2 -a 参数-a 参数可以替代 -r。除了递归同步以外，它还可以同步元信息（比如修改时间、权限、所有者等）。由于 rsync 默认使用文件大小和修改时间决定文件是否需要更新，所以 -a 比 -r 更常用。下面的用法才是标准的写法：$ rsync -a source destination目标目录 destination 如果不存在，rsync 会自动创建。执行上面的命令后，源目录 source 被完整地复制到了目标目录 destination 下面，即形成了 destination/source 的目录结构。如果只想同步源目录 source 里面的内容到目标目录 destination，则需要在源目录后面加上斜杠：$ rsync -a source/ destination上面命令执行后，source 目录里面的内容会被直接复制到 destination 目录里面，并不会在 destination 下面创建一个 source 子目录。3.3 -n 参数如果不确定 rsync 执行后会产生什么结果，可以先用 -n 或 --dry-run 参数模拟执行的结果。$ rsync -anv source/ destination上面命令中，-n 参数模拟命令执行的结果，并不真的执行命令。-v 参数则是将结果输出到终端，这样就可以看到哪些内容会被同步。3.4 --delete 参数默认情况下，rsync 只确保源目录的所有内容（明确排除的文件除外）都复制到目标目录。它不会使两个目录保持相同，并且不会删除目标目录中多余的文件。如果要使得目标目录成为源目录的镜像副本，则必须使用 --delete 参数。这将删除只存在于目标目录、不存在于源目录的文件。$ rsync -av --delete source/ destination上面命令中，--delete 参数会使得 destination 成为 source 的一个镜像。四、排除文件4.1 --exclude 参数有时，我们希望同步时排除某些文件或目录，这时可以用 --exclude 参数指定排除模式。$ rsync -av --exclude='*.txt' source/ destination # 或者 $ rsync -av --exclude '*.txt' source/ destination上面命令排除了所有 TXT 文件。注意，rsync 默认会同步以"点"开头的隐藏文件。如果要排除隐藏文件，可以这样写 --exclude=".*"。如果要排除某个目录里面的所有文件，但不希望排除目录本身，可以写成下面这样：$ rsync -av --exclude 'dir1/*' source/ destination多个排除模式，可以用多个 --exclude 参数：$ rsync -av --exclude 'file1.txt' --exclude 'dir1/*' source/ destination多个排除模式也可以利用 Bash 的大括号的扩展功能，只用一个 --exclude 参数：$ rsy…

Systemd 入门教程：实战篇
type: item
date: 2026-03-30T09:31:04+00:00
description: 编者注：本文为历史博文归档；涉及 JDK、框架与工具链版本请以当前官方文档为准。引用外链图片可能失效，阅读时请注意时效性。上一篇文章介绍了 Systemd 的主要命令，本文将介绍如何使用它完成一些基本的任务。一、开机启动对于支持 Systemd 的软件，安装时通常会自动在 /usr/lib/systemd/system 目录添加一个配置文件。若想让该软件开机启动，可执行以下命令（以 httpd.service 为例）：$ sudo systemctl enable httpd上面的命令相当于在 /etc/systemd/system 目录添加一个符号链接，指向 /usr/lib/systemd/system 里面的 httpd.service 文件。这是因为开机时，Systemd 只执行 /etc/systemd/system 目录里面的配置文件。这也意味着，如果把修改后的配置文件放在该目录，就可以达到覆盖原始配置的效果。二、启动服务设置开机启动以后，软件并不会立即启动，必须等到下一次开机。如果想现在就运行该软件，需要执行 systemctl start 命令。$ sudo systemctl start httpd执行上面的命令以后，有可能启动失败，因此要用 systemctl status 命令查看一下该服务的状态。$ sudo systemctl status httpd httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled) Active: active (running) since 金 2014-12-05 12:18:22 JST; 7min ago Main PID: 4349 (httpd) Status: "Total requests: 1; Current requests/sec: 0; Current traffic: 0 B/sec" CGroup: /system.slice/httpd.service ├─4349 /usr/sbin/httpd -DFOREGROUND ├─4350 /usr/sbin/httpd -DFOREGROUND ├─4351 /usr/sbin/httpd -DFOREGROUND ├─4352 /usr/sbin/httpd -DFOREGROUND ├─4353 /usr/sbin/httpd -DFOREGROUND └─4354 /usr/sbin/httpd -DFOREGROUND 12 月 05 12:18:22 localhost.localdomain systemd[1]: Starting The Apache HTTP Server... 12 月 05 12:18:22 localhost.localdomain systemd[1]: Started The Apache HTTP Server. 12 月 05 12:22:40 localhost.localdomain systemd[1]: Started The Apache HTTP Server.上面的输出结果含义如下：Loaded 行：配置文件的位置，是否设为开机启动。Active 行：表示正在运行。Main PID 行：主进程 ID。Status 行：由应用本身（这里是 httpd）提供的软件当前状态。CGroup 块：应用的所有子进程。日志块：应用的日志。三、停止服务终止正在运行的服务，需要执行 systemctl stop 命令。$ sudo systemctl stop httpd.service有时候，该命令可能没有响应，服务停不下来。这时候就不得不强制终止进程了，向正在运行的进程发出 kill 信号。$ sudo systemctl kill httpd.service此外，重启服务要执行 systemctl restart 命令。$ sudo systemctl restart httpd.service四、读懂配置文件一个服务怎么启动，完全由它的配置文件决定。下面就来看，配置文件有些什么内容。前面说过，配置文件主要放在 /usr/lib/systemd/system 目录，也可能在 /etc/systemd/system 目录。找到配置文件以后，使用文本编辑器打开即可。systemctl cat 命令可以用来查看配置文件，下面以 sshd.service 文件为例，它的作用是启动一个 SSH 服务器，供其他用户以 SSH 方式登录。$ systemctl cat sshd.service [Unit] De…