2026/10/21 12:39:22

Linux自学第三天:从安装nginx到权限与日志排查的完整实战

Linux自学第三天:从安装nginx到权限与日志排查的完整实战 1. 为什么偏偏是第三天严格来说我不是什么有天赋的学习者。前两天我还在跟终端里的黑框框大眼瞪小眼甚至一度怀疑自己是不是买了个假的Linux系统。第一天装好系统之后我干得最多的事情就是打开浏览器然后把它关掉再打开文件管理器再关掉。到了第二天我终于鼓起勇气敲了ls、cd、pwd这几个命令当时心里想的其实是“这不就跟Windows里的文件夹差不多嘛有什么好吹的。”但第三天开始事情变得不一样了。不是因为我突然开窍而是因为我的第一个实际需求出现了我要在Linux上做一个简单的网页测试环境需要装一个服务端程序还要让它开机自己跑起来。这个需求让我意识到前两天的“玩一玩”阶段结束了接下来面对的是一个真正要动手、要动脑的系统。所以这篇文章的记录是从“第三天早上打开终端”开始的。这篇文章适合谁看如果你正在自学Linux可能和我一样还在前期摸索阶段那么这篇文章里记录的思路、命令、踩坑过程应该会对你有帮助。如果你已经学了一段时间大概率也能从我的错误里找到点共鸣。我不讲那种动不动就要背几千条命令的“高手方法论”我只讲我在第三天实际做了什么、遇到了什么、以及我是怎么从一团乱麻里把问题捡起来的。2. 第三天早晨我的第一个真实任务2.1 任务拆解而不是直接开干我的目标是搭建一个简单的本地网页服务。听起来不复杂但当我坐下来准备操作时发现自己其实连“服务”这个词在Linux里意味着什么都不太清楚。Windows下我可能就双击一个安装包下一步下一步完事。但在Linux里我面对的是一个终端一个没有图形界面的“裸环境”所有操作都要自己一步步拼出来。我给自己定了三条路第一搞清楚我现在用的这个发行版怎么安装软件包第二搞清楚服务程序装完之后放在哪里、怎么启动第三搞清楚怎么让它开机自动运行还要能随时看日志。这三件事每件单独拎出来都不至于让人崩溃但合在一起就足以让一个初学者在第三天早上对着屏幕发呆半小时。2.2 确认环境和版本是学习的第一步很多新手容易忽略的一件事是不同Linux发行版之间的操作习惯差异很大。我前两天用的命令到了第三天才发现有些是当前系统自带的有些则压根不存在。为了避免“命令不存在”这种尴尬我先花了几分钟确认环境信息。我敲的第一组命令是这样的uname -a cat /etc/os-releaseuname -a显示内核版本、主机名、架构这些信息cat /etc/os-release则能让我清楚看到当前发行版的名称和版本号。我看到的结果是“Ubuntu”以及某个具体版本号心里就有底了接下来查资料时只要搜索Ubuntu相关的教程基本都能对上。这里有个小建议不要跳过环境确认这一步。它虽然不产生任何“成果”但能帮你省下后面大量排查问题的时间。毕竟你在网上搜到一条命令结果发现在自己的环境里不能用那不是命令的问题而是环境差异的问题。2.3 刷新软件源安装一切软件的前提确认完环境之后我尝试安装第一个软件包。当时我凭记忆敲了install开头的一条命令结果立刻被提示没有找到相关命令。后来我才知道Ubuntu下安装软件包的工具叫apt而它的完整用法需要配合子命令使用。我当时执行的是sudo apt updatesudo是提权用的意思是“以管理员身份执行”。apt是包管理工具update会从软件源服务器获取最新的软件包列表。这步操作让我第一次直观感受到Linux和Windows的一个本质区别Linux的软件安装是依赖“源”的它不是从某个网站下载一个exe文件而是从一个配置好的软件源仓库里拉取并解决依赖关系。跑完update之后屏幕上刷出一堆进度条我当时其实也没完全看懂那些数字只知道最后出现了一行类似“所有软件包均为最新”的提示。不管怎么说这一步跑通了接下来就可以正式安装程序了。3. 第一道坎软件包安装与依赖地狱的初体验3.1 安装一个程序居然要装一堆“顺便”的东西我准备安装的是一个轻量级网页服务器软件因为只是想测试所以选择了体积小、配置简单的方案。命令是sudo apt install nginx输入这行命令后系统问我是否继续我按了y然后就看着终端刷出一整屏的新软件包信息。这里面除了nginx本身还有一堆我完全不认识的名字。当时我的第一反应是“我到底装了多少个东西”这个感受特别典型。Linux的软件管理系统中一个软件包往往会依赖另外一些软件包而这些被依赖的包又可能依赖更多的东西。这不是坏事儿它在帮你把所有需要的零件一次性备齐但对于新手来说确实容易产生“失控感”。我后来才知道这个机制叫“依赖管理”是Linux软件生态相对稳定的根基。apt默认会把依赖包一起装好不需要我手动操心。这一点比Windows下那种“你缺个运行库自己去官网找”的体验要省心很多。3.2 装完之后我怎么知道它去哪了安装过程结束以后我面临一个新问题“这东西到底装哪了”Windows里我会去“开始菜单”里找图标但Linux服务器环境里没有开始菜单程序也不是简单躺在某个固定文件夹里。我试了which nginx返回了一个路径类似/usr/sbin/nginx。于是我开始了解Linux目录的大致分工/usr/bin和/usr/sbin是普通用户和管理员命令所在的地方/etc是配置文件的家nginx的配置很可能就在/etc/nginx/下/var/log是日志的大本营/var/www或/usr/share/nginx/html之类的地方通常是默认网页文件的所在目录。我是怎么验证的直接用了ls /etc/nginx/果然看到了nginx.conf和一堆乱七八糟的子目录。这个发现对当时的我来说几乎等于找到了新世界的入口——原来Linux不是没有“安装目录”而是它把不同功能的文件分散到不同目录里各司其职。3.3 如何启动一个服务安装完之后我照着直觉去执行了可执行文件结果发现前台一直被卡住了终端完全被日志刷屏连命令都敲不进去。我意识到这不是正确的启动方式。后来我查到管理服务的方法通常是用systemctl命令sudo systemctl start nginx sudo systemctl status nginxstart是启动服务status是查看运行状态。执行完status后终端上会显示一段状态信息包括当前进程是否在运行、有没有报错、占用资源情况等等。我看到状态栏里写着active (running)的那一刻整个人是有点激动的。说实话这个“active (running)”在别人眼里就是几个英文单词但在我第三天的认知里它意味着我成功把一个后台程序拉起来了而且是通过真正的Linux管理方式搞定的。4. 权限新手和系统打架的重灾区4.1 为什么总提示 “Permission denied”装好并启动nginx之后我想修改一下默认网页内容把我自己的HTML文件放进网站的根目录。当我兴冲冲地用cp命令复制文件时却收到了一条冷冰冰的提示Permission denied我第一次看到这行字时心里的独白是“这是我自己的电脑凭什么不让我动”后来才知道在Linux里文件和目录有一整套权限体系权限不够就是不够哪怕你觉得自己是电脑的主人也不行。权限这个东西我用一个类比才彻底理解Linux把每个文件和目录看成带了三把锁的箱子一把管“读”一把管“写”一把管“执行”。这三把锁分别对应三类人文件所有者、文件所属组、其他用户。用ls -l查看文件时那一串类似-rw-r--r--的字符就是在展示这些锁的开关状态。我当时执行的命令是ls -l /var/www/html/输出结果显示默认的网页文件是root用户所有的且普通用户没有写权限。这其实是一个安全设计防止普通用户随意篡改系统级的网页内容。但如果我真的要改文件该怎么办两个思路第一用sudo强制提权操作第二修改文件的所有者或权限。4.2 修改权限的“三板斧”我的第一个思路自然是sudo但后来发现如果每个文件都要用sudo去编辑时间长了会很别扭。于是我开始接触chmod和chown。chown用来改变文件所有者比如sudo chown -R 我的用户名 /var/www/html-R表示递归对目录及其内部所有文件生效。执行完之后我再用ls -l查看发现文件的所有者变成了我自己这个时候就拥有了直接修改的权限。chmod则用来改变权限位常见用法有两种符号模式和数字模式。我一开始觉得数字模式很难记直到有人告诉我r4、w2、x1把它们相加就好。比如755表示所有者可读写执行7组内用户可读执行5其他用户可读执行5。这样记起来就顺多了。我把自己的网页目录权限设置成了755然后在里面新建了一个index.html再次用浏览器访问终于看到了我自己写的页面。那一刻的成就感比第一次看到active (running)还要强烈。5. 第三天最值钱的收获学会看日志5.1 程序没问题为什么访问不了我把自己的网页内容替换进去之后浏览器打开却还是显示默认页面。我当时把配置文件翻来覆去地看也没看出哪里有问题。后来在一篇教程里看到一句话“Linux下排查问题第一步永远是看日志。”对就是日志。我顺着这个提示查看了nginx的日志目录ls /var/log/nginx/目录里通常有access.log和error.log。access.log记录每一次访问请求error.log记录程序运行时的错误信息。我当时用了一个命令去查看日志的最后几行tail -f /var/log/nginx/error.log-f参数的意思是“实时追踪”文件有新内容时自动追加显示。在我用浏览器重新访问网站之后error.log立刻吐出了一行错误信息内容是找不到某个具体路径下的文件。我顺着错误提示去检查发现是我把文件放错位置了一直放在自己创建的临时目录里而不是nginx实际读取的根目录。这件事给了我很深的印象Windows世界里出了问题很多时候是靠弹窗提示和重启解决但在Linux里程序未必会给友好提示它只会默默把错误记录在日志里。懂不懂看日志直接决定了你是“瞎猜者”还是“排查者”。5.2 日志里的常见关键词速查我把自己第二天到第三天积累的常见日志关键词整理了一下虽然不全面但作为新手备忘足够用了关键词可能的含义Permission denied没有权限检查文件所有者或权限位Connection refused服务没起来或者端口不对Address already in use端口被占用可能另一个进程占用着File not found路径不对或文件真的不存在command not found命令拼写错误或软件包未安装遇到问题时先打开对应日志搜索这些关键词通常能很快定位问题范围。这个方法在我第三天下午的排查过程中帮了大忙后续我相信也会一直用下去。6. 进程管理原来电脑里藏着这么多“分身”6.1 查看进程像查户口一样nginx跑起来之后我产生了一个疑问“它到底是怎么运作的为什么我关掉终端它还在运行”后来才知道这类服务程序会以“守护进程”的方式在后台运行不会随着终端的关闭而退出。为了验证我执行了ps auxps是“进程快照”命令aux是一组参数用来显示所有用户的进程列表。屏幕上刷出几页密密麻麻的信息我看到有好多条nginx相关的进程瞬间有点懵“我只启动了一个服务为什么有这么多”稍微多了解一点之后我才明白nginx采用的是多进程模型一个主进程用来管理全局再派生出多个工作进程来处理并发请求。这就像一家餐厅里主厨负责全局调度几个灶台师傅分别负责不同的菜客人再多也能同时出餐。用这种比喻去看进程列表就好理解多了。6.2 干掉一个卡死进程的正确姿势学进程管理的过程中我还碰到过一个“僵尸”进程。具体情况对方不重要重要的是我发现某个进程占用了CPU和内存始终不退出。我想把它关掉于是用上了kill命令。最简单的用法是kill 进程号但有时候进程比较顽固单次kill无效。后来我了解到kill其实是在向进程发送信号不同信号的含义不同kill -15是礼貌地请求进程退出给它时间收尾kill -9是强制终结不让进程做任何善后处理。我尝试的是先用kill -15发现那个进程还在最后只能上kill -9效果立竿见影。后来我学到一句经验口诀“平时能用15就不用9只有实在退不出去才强制。”因为直接强杀可能导致文件损坏或配置未保存这种风险还是尽量避免。6.3 观察资源占用top 初体验除了ps我还试了另一个命令top。top会动态刷新显示当前系统资源占用情况类似Windows的任务管理器。第一次进去时我被页面上花花绿绿的数据弄花了眼但这些数据里最关键的两栏是CPU占用和内存占用。如果某一栏一直居高不下就说明有进程在消耗大量资源需要重点关注。退出top的方式是按q键这一点是我折腾了好一会儿才发现的……当时差点把终端直接关掉重启实在有点丢人。7. 目录结构读懂了它就读懂了大半个系统7.1 从“文件都在哪”到“为什么这么放”第三天下午我决定不再东一榔头西一棒槌地乱敲命令了而是认真把Linux的目录结构底朝天看一遍。因为一整天都在各种路径之间跳来跳去如果不知道每个目录的基本用途永远只能靠死记硬背。Linux的根目录是/所有路径都从它开始。我把顶层目录列举了一遍ls /在我这个系统里显示出来的目录有bin、boot、dev、etc、home、lib、media、mnt、opt、proc、root、run、sbin、srv、sys、tmp、usr、var。每个目录名都不长但背后承载着不同的职责。我花了一个下午的时间逐一进入这些目录查看内容。比如/bin里放的是系统运行所需的基本命令/usr里是用户安装的软件/var是经常变化的数据比如日志和缓存/tmp是临时文件/home是普通用户的家目录。7.2 一个值得养的“家目录”习惯在家目录里我给自己建了一个专用的练习文件夹以后所有临时测试都放在这里不去污染系统目录mkdir -p ~/lab/logsmkdir -p的意思是连同上级目录一起创建如果~/lab不存在也会一并建出来。我在这个目录下创建了一些测试文件、脚本草稿以及一些从网上复制下来的练习代码。养成“所有实验都在自己家目录里做”的习惯可以避免很多安全问题。比如如果某个文件误删了至少不会影响到系统级文件。对于自学者来说这一点尤其重要因为我们动手试错的机会非常多而试错的代价不应该由整个系统来承担。7.3 用 find 找文件比眼睛靠谱下午我一度忘记某个测试脚本放在哪个子目录里了。在Windows下我可能会打开资源管理器一个个文件夹翻但在Linux终端里我学会了更高效的方案find ~/lab -name *.sh这条命令会在~/lab目录下查找所有以.sh结尾的文件。find的粒度可以很细可以按名字、按类型、按大小、按修改时间来找文件。对新手来说只要会用-name这一个参数就已经能解决大多数“我文件呢”的问题了。8. 文本处理三兄弟grep、awk、sed 的前世今生8.1 grep在垃圾堆里找针眼第三天遇到的问题里有相当一部分可以归结为“信息太多难以定位”。比如某个配置文件里有几十行内容但我只想知道其中和端口有关的那几行。这时候grep就派上了用场grep listen /etc/nginx/nginx.confgrep会逐行读取文件内容把包含指定关键词的行打印出来。我当时看到输出里确实有listen开头的几行才确认端口配置的位置。这个命令在排查日志、检查配置、过滤命令输出时几乎是无处不在的。我还学了一个特别常用的组合用法在查看某个软件运行状态时如果输出内容太多可以接一个管道符再交给grep过滤。管道符用|表示意思是“把前面命令的输出结果交给后面的命令继续处理”。比如ps aux | grep nginx这一条命令能直接把进程列表里跟nginx相关的行挑出来不用在一堆数据里慢慢找了。8.2 awk按列拆数据的好手如果说grep是“按行筛选”那么awk对我来说更像“按列拆数据”。比如我想知道日志文件里每一行的第一列是什么我可以这样操作awk {print $1} /var/log/nginx/access.log这个命令会读取文件每一行然后打印出第一个字段。awk支持的逻辑远不止这些但它对第三天的我来说已经是一个“能看懂输出里每一列代表什么”的得力工具了。整个过程就是从原始数据中抽出一列来看有点像Excel里只保留某一列一样。8.3 sed批量替换配置的利器一开始我修改配置都是用文本编辑器手动改后来发现遇到多个相似配置需要改动时手动编辑实在太慢。于是我开始接触sed的替换功能。sed最常用的一个小片段是sed -i s/旧内容/新内容/g 文件名-i表示直接修改文件s是替换动作g表示全局替换。意思就是把文件里所有“旧内容”全部替换成“新内容”。我在调整nginx默认端口时就是用这条命令把80换成了其他端口非常方便。但我后来也发现sed的替换是纯文本层面的如果你把某个路径写成变量形式用它就不太方便。对于新手来说先把这三个命令各自最核心的用法掌握住就足以应付日常操作了不必一开始就追求所有高级功能。9. 服务器配置的第一次完整闭环9.1 改配置之前先备份下午我觉得对系统有点感觉了开始尝试修改nginx的默认配置比如更换监听端口。第一次改之前我犯了一个几乎每个新手都会犯的错误忘记备份。后来我重新把配置文件复制了一份sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak这样做的意义在于一旦修改出错导致服务起不来我可以立刻用备份文件还原并重新加载。经历过一次“改了配置导致服务崩溃”之后我就把“先备份再修改”刻进了肌肉记忆。9.2 验证配置是否正确在修改完配置之后我没有直接重启服务而是先执行了sudo nginx -t这条命令会检查配置文件的语法是否正确。输出如果显示类似“syntax is ok”的提示说明配置至少没有格式问题。这个步骤极其重要因为如果配置有语法错误直接重启服务会把服务搞挂导致网站暂时无法访问。先验证再重启是降低风险的标准操作。9.3 重新加载配置而不是粗暴重启我一开始不知道“重启”和“重新加载”的区别直接用了systemctl restart nginx。后来才知道对于配置变更类操作更稳妥的方式是用reloadsudo systemctl reload nginxreload会让服务在不停机的情况下读取新的配置文件平滑生效。而restart则是先停止再启动过程中会有一段短暂的中断。对本地测试来说差别不大但如果以后部署真正的线上服务这个区别就会变得非常重要。整套流程走下来我算是把“修改配置、验证配置、重新加载配置、查看日志确认效果”这条链路完整跑通了一遍。这个闭环看起来简单但确实是我学Linux以来第一次独立完成的一件“正事”。10. 第三天踩坑实录三个最容易卡住新手的细节10.1 写错了路径还以为是命令不对我至少浪费了二十分钟在一个问题上输入nginx提示找不到命令但软件明明已经安装好了。后来发现原来当前的用户环境变量里没有包含/usr/sbin这个路径所以直接输入命令名时找不到它必须用完整路径/usr/sbin/nginx来执行。解决方式有两种一种是用完整路径执行另一种是把该路径加入环境变量。对新手来说优先使用完整路径更简单、更安全也能避免影响系统全局配置。这个坑的通用教训是命令提示找不到时不要马上怀疑软件没装好先用which 命令名或者ls /usr/bin/命令名查一下实际位置。10.2 端口被占用改配置还不够有一次我改了nginx监听端口以为重启之后必然生效结果访问还是失败。日志显示“端口已被占用”。我后来才意识到可能有其他程序占用了我要使用的端口。解决办法是先确认占用端口的进程sudo lsof -i :8080或者用sudo ss -tuln | grep 8080lsof能列出占用该端口的进程详情ss -tuln则是查看端口监听状态的常用命令。找到占用进程后要么关掉它要么换一个别的端口问题就迎刃而解了。10.3 改了配置没生效这个问题困扰了我很久配置文件明明改对了服务也重新加载了但访问结果还是老样子。最后发现是因为浏览器有缓存我看到的其实是旧页面。清掉浏览器缓存之后再访问新页面立刻就出来了。这件事的启示是问题不一定出在系统端有时候是你自己的“查看方式”有缓存。排查问题时不要只盯着终端也要考虑外部因素。11. 自我复盘与新手心法11.1 第三天结束时我到底掌握了什么我给自己列了一份清单把当天学到的东西做了一个汇总。这个习惯是从前两天开始养成的每天结束前都把零散的知识点收拢一遍第二天回顾时会特别有用。文件系统结构明白每个主要目录的职责软件包管理apt update、apt install、apt remove服务管理systemctl start/stop/status/reload权限体系chmod和chown的基本用法日志排查tail -f、grep查看日志关键词进程管理ps aux、kill、top文本处理grep过滤、awk取列、sed替换。说实话这些内容放在老手眼里全是基本功中的基本功。但对于三天前的我来说Linux还是一个“黑乎乎的、不知道点哪里才能运行程序”的系统。能走到这一步我自己是比较满意的。11.2 允许自己慢下来反而学得更快学Linux的第三天我最深的心得是不要急着一天就掌握所有命令。命令是无穷无尽的而且每条命令都有几十个参数想把它们全部记住根本不现实。更有效的办法是遇到一个问题去查解决方案然后动手做一遍做的时候自然而然就记住了最常用的部分。我举个例子如果我只背“mkdir是创建目录的”不实际去建几次目录那我永远不会有“用-p创建多级目录”的需求和认知。只有当我遇到“一次性创建a/b/c三层目录”的场景才发现单用mkdir会提示父目录不存在然后一查原来有mkdir -p这个参数。这种“先踩坑再补齐”的学习路径虽然慢但记忆非常牢固。所以如果你也在自学Linux不要被那些一天速成、三十天精通之类的说法吓住。每个人的知识背景不同有的人用Linux时间很长自然上手快有的人和我一样是零基础转过来那就允许自己一天只弄懂一个概念只要坚持一定会越走越顺。11.3 把错误记录成日志形成自己的排错手册从第三天开始我养成了一个习惯每次遇到报错不仅把解决方案记录下来还把当时的错误提示原文也记录下来。比如“Permission denied” 对应的是什么场景下发生的“command not found” 是在键入哪个命令时出现的“Address already in use” 最终是怎么解决的我用最简单的文本文件把这些信息保存起来按日期和关键词分类。这个文件虽然很简陋但它是我真正亲身踩坑换来的资料。以后如果再遇到类似问题直接查阅自己的记录比在网上重新搜索要高效得多。12. 第三天结束时我给自己的下一个任务12.1 从“会敲命令”到“能解决问题”第三天结束前我给自己设计了一个小挑战写一个简单的shell脚本把每天要做的环境检查动作自动化。这个挑战对我来说有点超前因为脚本语法我还不太熟但我觉得有挑战才有进步。脚本内容也不复杂就是每天打开终端后执行几条检查命令包括查看IP地址、查看服务状态、查看磁盘占用、查看内存占用。我发现这些操作我每天都要重复做干脆用脚本把它们串起来。这个想法虽然简单但让我第一次体会到“用Linux去自动化Linux操作”的感觉。脚本大概是这样的#!/bin/bash echo 当前登录用户$(whoami) echo 当前IP地址 ip addr show | grep inet echo nginx服务状态 systemctl status nginx echo 磁盘使用情况 df -h写完之后我用bash 脚本名执行了一下看到一串信息依次输出虽然还不懂每一行背后的原理但至少我知道自己已经在用程序员的思路来使用系统了。12.2 给自己定下第四天的主题第三天的核心是“把服务跑起来、把日志看懂、把权限理顺”。第四天我打算围绕“脚本化和自动化”继续深入学一学变量、条件判断和循环这些基础语法把今天这个简单脚本扩展成真正能帮我干活的工具。我给自己定的方向不是去啃大部头教材而是继续沿用“解决实际问题驱动学习”的方式。哪个环节不顺手就去查资料搞懂哪个环节。这个过程不需要多么高深的理论支撑只要前期每一步都走得扎实后面自然会顺畅起来。从第三天早晨对着终端不知所措到第三天晚上能自己写一个简单的检查脚本这种变化其实是真实且踏实的。Linux并没有传闻中那么可怕只是它需要你换一种方式去理解“用电脑”这件事你不再只是点按钮的人而是逐步变成告诉系统“该干什么”的人。这条路才刚开始但方向已经清楚了。