尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Linux高频命令实战:文件操作、文本处理与Shell脚本避坑指南

Linux高频命令实战:文件操作、文本处理与Shell脚本避坑指南 没想到会以“重温”的方式来写Linux命令。前阵子帮朋友排查一台老服务器的性能问题登录上去之后发现好多命令都开始“想不起来”——不是不会用而是不假思索敲出去的东西越来越少更多时候是直接搜、直接复制。这让我意识到一个问题用了这么多年Linux真正刻在脑子里的、遇到任何环境都能直接用的命令其实就那么几十条而这几十条的细节恰恰是最容易被忽略的。所以这篇博文不是入门教程也不是命令大全的翻译而是我基于几年实际运维和开发经验把高频命令重新梳理了一遍。文章会覆盖文件操作、文本处理、网络排查、进程管理、软件安装、容器化以及Shell脚本中容易踩坑的命令细节目标读者是那些已经用过Linux一段时间但想系统化巩固、发现自己“知其然不知其所以然”的人。内容尽量贴近实际操作每个命令都穿插真实场景和踩坑记录希望能帮你省掉一些摸索时间。1. 文件与目录删除、权限和查找里那些容易翻车的细节Linux命令里敲得最多的永远是文件操作。但恰恰是最常用的部分最容易出问题。1.1 rm -rf 的边界删除文件夹到底怎么删才安全热搜词里“linux删除文件夹命令”排得很靠前说明很多人对这个高频操作还是有疑虑。最直白的答案是rm -rf 目录名。但完整说清楚得先拆开看rm file删除单个文件。rm -r dir递归删除目录。rm -f file强制删除不提示确认。rm -rf dir递归强制删除目录这是真正的“毁灭性”组合。我见过不少人在生产环境把rm -rf /或者rm -rf .敲出去结果就是整个系统文件被清空。为什么会发生很简单的逻辑rm -rf后面的参数一旦是变量而变量值为空命令就会变成rm -rf /。所以这里有一条必须刻在脑子里的规矩写脚本或在生产环境操作时永远不要直接使用rm -rf加变量的写法。先用echo把路径打印出来确认一遍或者加上--来终止选项解析例如rm -rf -- $dir。更稳妥的做法是用mv代替rm把要删除的内容移动到/tmp下的某个目录确认没问题再清空。这就是“软删除”思路成本极低但能救回很多误删。我个人的习惯是危险操作前先ls -la看一眼目录内容批量删除时先find出来数量再决定是否执行。比如删3天前的临时日志find /var/log/nginx -name *.log -mtime 3 -exec ls -l {} \; # 确认文件列表ok再换成 -delete 或 -exec rmrmdir命令只能删除空目录平时用到的机会不多但如果是脚本里需要非常安全地删除一个目录rmdir反而是最佳选择——非空目录它会报错不会误伤内容。1.2 权限位不只是rwxsetuid、setgid和粘滞位权限相关的热搜词“linux新建用户”其实也和文件权限强相关。这里不展开useradd的完整流程只讲一个多数人查了又忘的知识点权限位里的特殊标志。chmod 755 file、chmod 644 file这类基础操作大家都会但遇到chmod 4777、chmod 1777时很多人会卡住。这里的4、2、1分别对应setuid4以文件属主身份运行程序。典型例子是/usr/bin/passwd普通用户执行它时可以临时获得root权限来修改密码。setgid2文件以属组身份运行或者在新文件中继承目录的属组。用于团队协作目录非常有用。sticky bit1粘滞位。典型例子是/tmp目录权限1777用户可以在里面创建文件但只能删除自己拥有的文件避免互相破坏。用ls -l查看时它们显示为rws、r-s或rwt。遇到-rwsr-xr-x这种权限位能一眼读出setuid算是Linux基本功。新建用户时还有个容易忽略的细节useradd和adduser是两个不同的东西。CentOS/RHEL系用useraddDebian/Ubuntu系的adduser是一个交互式脚本行为不完全一样。建议生产环境统一用useradd加参数的方式可预期性更强useradd -m -s /bin/bash -G wheel zhangsan passwd zhangsan-m创建家目录-s指定Shell-G附加组。顺序无所谓但参数不能漏否则用户登录后可能连家目录都找不到。1.3 find、locate、which、type按需选工具查找文件时很多人第一反应就是find . -name xxx。其实这四个命令各有分工选对了能省大量时间命令用途特点find按文件名、大小、时间、权限等条件在目录树中搜索实时搜索功能最强但磁盘IO开销大locate基于数据库快速定位文件极快但数据库不是实时的新文件可能找不到which在PATH中查找可执行命令只看PATH目录常用于判断命令是否安装type判断命令是内建命令、别名还是外部命令比which更底层直接看Shell是怎么识别这条命令的find我最常用的几个组合find /data -name *.log -mtime 30 -size 100M find /data -type f -user root -perm -4000 2/dev/null find /data -type d -empty -delete第一个是找30天前、超过100M的日志文件第二个是找设置了setuid的文件安全审计常用第三个是删除空目录。find -exec和xargs的组合我在第三章会专门说。关于type命令多说一句type -a ls会列出所有叫ls的命令来源能看到alias和环境下的真实路径。排查“为什么我敲的命令和实际执行的不一样”时这个命令是第一把钥匙。2. 文本处理vim、grep、sed、awk的重温路线Linux的哲学是一切皆文件所以文本处理能力基本决定了你在命令行下的生产效率。这一章我按“编辑器→搜索→流处理”的顺序来理。2.1 vim把移动和替换练成肌肉记忆热搜词里“vim命令”持续有人搜说明这玩意确实需要反复记。我不打算贴操作速查表只讲三个“用起来才是真的会”的层面。第一移动比插入更值得练。很多人用vim还停留在上下左右箭头效率提升的第一步是强制自己用hjkl然后记住这几组跳跃w/b按单词前进/后退。0/$跳到行首/行尾。gg/G跳到文件首/尾。Ctrl-d/Ctrl-u向下/向上翻半屏。f 字母行内跳到下一个指定字符。移动熟练了配合d删除、c修改、y复制、p粘贴几乎任何编辑动作都能在两次按键以内完成。比如d$就是删到行尾ct.就是把当前位置到下一个点号之间的内容全部替换。第二搜索替换是高频场景。很多人改配置文件还在手动找其实有完整的语法:%s/old/new/g 全文替换不加g只替换每行第一个 :%s/old/new/gc 替换前逐个确认 :5,20s/old/new/g 只在5到20行之间替换s后面跟的定界符不一定非用/遇到内容里带斜杠的可以换成:或#比如替换URL时:%s#http://#https://#g就不会把格式搞乱。第三多文件操作要会。一次改十几个配置文件时vim file1 file2然后:bn下一个缓冲区、:bp上一个、:ls列出所有缓冲区比开十几个终端窗口高效得多。实操建议关掉vim的兼容模式在~/.vimrc里写上set nocompatible、set hlsearch高亮搜索结果。用了十年vim这几行配置带来的体验提升比装任何插件都明显。2.2 grep、sed、awk日志分析的黄金组合处理日志时grep负责查sed负责改awk负责拆列三者组合能解决绝大多数文本处理需求。grep的高频参数就几个-E用扩展正则、-v反向匹配、-c统计次数、-l只列文件名、-r递归目录。排查报错时我最常用的是grep -E ERROR|Exception app.log | tail -100先确认报错集中出现在哪个时间段再往前翻上下文。sed最经典的是打印指定行范围的日志用来定位崩溃前的现场sed -n 100,120p app.log # 打印100到120行 sed -n /2025-01-01 10:00/,/2025-01-01 11:00/p app.log第二个命令是打印时间段内的所有日志效果等同于awk里用时间字符串做条件过滤但sed写起来更简洁。awk的核心思想是“按列处理”。默认按空白分列$1是第一列$0是整行NF是列数NR是行号。日志分析最常见的需求就是从访问日志里统计状态码分布awk {print $9} access.log | sort | uniq -c | sort -rn这行的意思是取第9列HTTP状态码排序统计每个值的出现次数再按次数倒序。一句命令就能看到500错误是不是暴增。awk还能做求和、求平均、字符串截取复杂报表也可以直接在上面写我甚至见过同事用awk写了个几十行的采集脚本扛住了监控系统没部署前的临时需求。2.3 管道、重定向和xargs的配合管道和重定向的理论大家都懂但组合起来有几个细节值得重申。会覆盖文件会追加这个基础但重要。用重定向到日志文件时一旦写错目标文件内容是找不回来的。安全习惯是涉及覆盖操作的命令先确认当前目录再确认目标文件是不是要覆盖的那个。xargs是管道的“接力棒”专门用来把前一个命令的输出变成后一个命令的参数。最容易踩坑的地方是文件名带空格。比如find . -name *.txt | xargs rm如果文件名里恰好有空格xargs会把一个文件名拆成两个rm就会报错甚至误删。正确的做法是用-print0和-0组合find . -name *.txt -print0 | xargs -0 rm这里-print0让文件名之间用空字符而不是换行分隔xargs -0按同样规则解析空格、特殊字符都不会有问题。另一个常用参数是-n比如xargs -n 1表示每条命令只传一个参数批量执行某些操作时很有用。3. 网络排查从telnet到iptables的命令链网络问题排查是整个运维工作中最吃命令功底的场景。这一章我按“端口通不通→哪一段不通→是不是被防火墙拦了”这条链路来写。3.1 telnet ip 端口怎么看通不通热搜词“telnet命令怎么用”“telnet ip 端口 命令怎么看通不通”其实是同一个问题。telnet的正经用途是远程登录但现在登录早被ssh取代剩下的主要功能就是探测端口通不通。telnet 192.168.1.100 3306执行后会有三种结果分别对应三种结论返回信息含义Connected to ... Escape character is ^]端口通则直接打到了对方的TCP监听Connection refused目标端口没有服务监听或服务没启动长时间卡住直到超时中间有防火墙丢弃包或者IP不可达实际排障时telnet“通”与“不通”的含义要理解准确。它验证的只是TCP层的连通性不代表应用层服务正常。比如MySQL端口通但密码错了照样连不上HTTP端口通但nginx可能返回500。所以telnet的定位是“第一步探测”不能替代后面的业务验证。现代系统里ncnetcat和curl更常用nc -vz 192.168.1.100 3306 curl -v telnet://192.168.1.100:3306 timeout 3 bash -c echo /dev/tcp/192.168.1.100/3306 echo port open第三种方式不需要装任何额外的包只要bash支持/dev/tcp就能用于端口探测在一些精简容器镜像里特别好用。3.2 ping、traceroute、curl、ss的分工很多人排查网络时只会用ping,发现能通就认为网络没问题。实际上这四个命令在排障链上各管一段。ping验证的是ICMP层的连通性也就是“主机之间能不能通”。它最实用的输出是TTL和丢包率。丢包率高说明线路不稳TTL数值异常说明中间跳数有变化比如从正常情况下跳到另一个区域。但要注意很多云服务器默认禁ping这时候ping不通不代表服务不通换curl测就对了。traceroute用来定位“到底断在哪一跳”。格式是traceroute -n 目标IP加-n避免做DNS反向解析散布延迟。排障时看到中间某跳一直* * *就是那一跳不回应或丢弃了但不一定是故障有些路由节点出于安全策略就是不回包。curl是最贴近业务的连通性验证工具。curl -I https://example.com只拿响应头curl -v显示完整握手过程-m设置超时防止卡死curl -v -m 5 https://example.com/api/health如果端口能用在HTTP层却报错curl -v给出的错误信息几乎能直接告诉我们问题出在DNS、TLS还是HTTP协议本身。这个命令我在接口联调和故障定位时用的频率比ping高得多。ss是用来替代netstat的连接查看命令。查看所有监听端口ss -tulnp它比netstat快得多输出也更干净。排查“服务起了但没有监听”或者“端口被占用”时这个命令是首选的。类似的还有lsof -i :8080在排查端口占用时lsof给出进程PID和进程名清晰直观。3.3 iptables的基础逻辑与规则查看安全相关的热搜词“iptables命令详解”排得很高。iptables虽然是老技术但现在生产环境特别是云服务器上仍然大量存在。iptables用“表链”组织规则filter表管过滤nat表管地址转换mangle表管报文修改。日常用的最多的是filter表的INPUT、OUTPUT、FORWARD三条链。查看规则是最常用的操作iptables -L -n -v --line-numbers-L列出规则-n不做反向解析-v显示包计数和字节数--line-numbers显示行号方便删除指定规则。看到某条规则有大量包命中count持续增长说明流量确实走到了这条规则如果一条都没命中规则的顺序或匹配条件可能有问题。新增一条放行规则iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT-A追加到链尾-p协议-s源地址-j动作。一个常见误区是规则追加到链尾后如果前面已经有DROP ALL规则新加的放行规则永远不会生效。所以修改防火墙策略时正确顺序是-I插入到指定位置或者把DROP ALL放在链尾。排查“telnet不通但服务正常”的经典链路是先ss -tulnp确认服务监听再iptables -L -n -v确认是不是被防火墙拦了最后看目标机器上是不是有firewalld或ufw这类上层工具。3.4 安全测试场景下的sqlmap与授权边界热搜词里有“sqlmap命令”这个工具经常被误解作为一篇向从业者输出的博文我这里明确说一句sqlmap是一款自动化检测SQL注入漏洞的安全测试工具只能用于你拥有明确授权的目标。渗透测试、等保测评、护网行动这类场景使用它才合规平时拿它扫描不属于自己的站点不但违规而且很可能触犯相关法律。sqlmap一次完整测试的命令格式是sqlmap -u http://target.com/index.php?id1 --batch --banner先探测注入点再获取目标指纹。这里的合理用法是配合一个你部署的、允许测试的靶场比如本地的DVWA或sqli-labs练习环境。安全测试的核心不只是工具怎么用而是用之前确认自己的边界在哪里。把边界意识放在工具前面这一行才算真正值钱。4. 进程与系统资源top之外的性能分析命令之前在热搜词里看到“top命令详解”“linux面试题”都排在比较前面说明这类命令的不只是我在复习很多人在面试或处置线上故障时也经常被问住。这一章我重点讲top的读法以及它之外的组合命令。4.1 top命令详解从一堆数字里快速定位问题top打开后是一整屏动态刷新的数据新手容易看得一团浆糊其实只要抓住几个核心区块。第一行是系统概况重点是load average后面的三个数字。它们分别表示1分钟、5分钟、15分钟的平均负载。判断负载是否过高不能只看绝对值要看它和CPU核数的关系。四核机器负载接近4是“跑满了”接近8就是严重超载但一个64核的机器负载10可能还远没到瓶颈。第二行的进程数和第三行的CPU状态是关键。us用户态CPU占比程序的业务逻辑在跑。sy内核态CPU占比系统调用频繁或内核处理量大。waI/O等待进程在等磁盘或网络。id空闲CPU。st被虚拟机管理程序偷走的CPU在云服务器上常见。举个例子top显示wa长期超过30%别的指标都很低那问题十有八九出在磁盘I/O而不是CPU下一步就该用iostat看了。进程列表的排序默认是按CPU使用率。按P按CPU排序按M按内存排序按1展开每个核的单独状态。想杀死一个进程直接按k输入PID比退出top再敲kill快得多。占用内存的字段里VIRT是虚拟内存总量RES是实际驻留内存SHR是共享内存。排查内存问题时主要看RESVIRT很大但RES很小通常不用慌可能只是程序申请了但还没实际使用。4.2 ps、free、df、iostat、dstat组合拳top看的是“此刻”的状态如果要看进程快照用ps。ps -ef | grep java ps aux --sort-%mem | head -20第一行查某个进程是否在跑第二行找出内存占用最高的前20个进程。ps aux里的VSZ和RSS与top的VIRT和RES对应含义相同。查内存用free -h。-h参数自动换算成人类易读的单位。这里有个常见的迷惑点free显示buff/cache占了很多内存看起来好像内存不够了。但实际上buff/cache在系统内存不足时可以被内核自动回收真正需要关注的是available那一列它才是“实际可用”的内存。查磁盘用df -h看剩余空间df -i看inode。inode耗尽是生产环境一个很容易被忽略的坑df -h显示磁盘还有几十G但程序就是创建不了文件很可能就是inode耗尽了小文件太多每个文件都要消耗一个inode。这时候df -i立刻能看出来。I/O诊断用iostat重点看%util和await两个指标。%util接近100%说明磁盘一直忙await高说明响应慢。这两个指标不能单独看一个请求越多的场景await高是正常现象需要结合读写量一起判断。dstat是一个能同时看CPU、内存、磁盘、网络的汇总工具一条命令把所有关键指标打出来dstat -tcml --disk-util排查线上问题时dstat打一个窗口基本能覆盖“资源到底卡在哪”的大部分疑问。4.3 systemctl与journalctl服务排障的前两步服务起不来是Linux运维的高频问题。systemctl是Systemd体系下的服务管理命令排障时印在脑子里的两步是systemctl status nginx journalctl -u nginx -fsystemctl status会告诉你服务的当前状态、主进程PID、最近几条日志如果是failed状态错误原因往往就在这最后几行。journalctl -u nginx -f则是跟踪这个服务的系统日志-f持续输出报错现场多半就在这里出现。服务无法启动的原因常见的有配置文件语法错误、端口被占用、权限不足、依赖的服务没起来。逐个排查时systemctl status确认状态journalctl看日志ss -tulnp确认端口占用基本能覆盖90%的场景。systemctl enable/disable控制开机自启。这里提醒一点很多教程会直接写systemctl enable nginx但如果在禁用状态下第一次设置开机自启应该用systemctl enable --now nginx一次完成“设置开机自启立即启动”两个操作避免忘了start。5. 软件安装与容器化从yum/apt到docker、containerd软件安装贯穿日常操作而容器化之后的命令生态又和传统包管理有很多交集。这一章把两边的关键点串起来。5.1 包管理器的坑源、依赖与版本锁定Linux发行版不同包管理器也不同。Debian系用aptRHEL系用yum/dnf工具命令有差异但核心概念相通。先说要养成的第一个习惯安装软件前先更新软件源。很多“装不上”的问题其实只是源里的索引太旧apt update apt install nginx # 或 yum makecache yum install nginx第二个坑是依赖冲突。apt/yum会尝试自动解析依赖但如果手动下载某个软件包强装比如dpkg -i xxx.deb依赖就没人管了可能出现“装了之后其他程序起不来”的情况。需要手动补依赖时apt -f install或yum install -y会尝试修复依赖关系这是解决这类问题的常规手段。第三个坑是版本漂移。相同软件在测试环境装的是1.0生产环境装成了1.2某个配置项的行为可能就变了。需要用apt-mark hold package或yum versionlock package把版本锁住测试环境验证过的版本生产环境部署时用同样的锁定策略这类问题就不会反复出现。不管哪个发行版都有一种不推荐但很多人干过的安装方式从网上随手复制一个./configure make make install源码编译。源码编译不是不行但依赖问题会瞬间放大十倍。一个常见的建议是能用发行版软件源安装的就用软件源源里没有就找维护者提供的官方仓库或二进制包实在没有才考虑源码编译。5.2 docker安装与containerd命令的关系热搜词“linux安装docker”和“containerd命令”可以放一起讲因为现在Docker的底层运行时几乎都是containerd。一个标准的Docker安装流程是sudo apt install docker.io # 或 curl -fsSL https://get.docker.com | sh这里稍微提一句curl | sh这类“从网络拉取脚本直接执行”的安装方式确实方便但安全前提是你能确认脚本来源可信任、且脚本内容没有问题。生产环境安装时我是先把脚本下载下来重点看里面有没有奇怪的下载源和可疑命令确认过再执行。安装完成后docker version能看到Client和Server两个部分。Server部分如果显示containerd作为容器运行时说明当前就是“docker客户端→dockerd→containerd”的三层结构。实际上docker命令的高频操作在containerd层面都有对应的原生命令Docker命令containerd辅助工具crictl/nerdctldocker pullcrictl pulldocker runcrictl run参数复杂/nerdctl run与docker类似docker pscrictl psdocker logscrictl logs如果你的环境里有Kubernetes那crictl几乎是必装的排查工具。它按CRI标准对接容器运行时crictl ps -a能看到所有容器状态crictl logs取日志crictl inspect查看容器详细配置。排查节点上“容器一直CrashLoopBackOff”这类问题时我习惯的顺序是crictl ps -a看容器状态crictl logs看应用日志再crictl inspect看配置和挂载。这套流程在K8s节点排障时比进每个Pod手敲kubectl还要直接。5.3 conda与git开发环境里的两个高频命令开发场景下的Linuxconda和git基本每天都在用。conda解决的痛点是Python环境的隔离和依赖管理。新建环境conda create -n py39 python3.9 numpy pandas conda activate py39 conda deactivate这个组合能保证不同项目的依赖互不干扰。很多人装conda只用了conda install一个命令其实环境隔离才是conda的核心价值。创建环境时一次性把常用包列全比装完一个发现少一个再补装要省时间。git命令里最常用的链路是git clone gitgithub.com:user/repo.git git add . git commit -m update git push origin main更值得重视的是.gitignore和git log --oneline --graph这类“看得清历史”的能力。排查“代码到底哪一行开始出问题的”时git log -p配合git blame能精确定位每次变更和每一行的最后修改者。备份开发环境时pip freeze requirements.txt或conda env export environment.yml是必备操作。第一次就因为没做这件事重装系统后把整个环境的包一个个重新装回来一个下午就没了。趁环境还能用先把清单导出来放好。6. Shell脚本里的命令搭配shift、type与参数处理的细节写脚本是命令的进阶用法这一章用几个实际场景来说明参数处理和命令调用的“隐藏细节”。6.1 shift命令位置参数的滚动式消费shift在Shell脚本里每次把位置参数整体左移一位$2变成$1$3变成$2原来$1的内容被丢弃。这个机制在做命令行参数解析时非常有用。例如写一个部署脚本需要同时支持多个选项参数#!/bin/bash while [ $# -gt 0 ]; do case $1 in -h | --help) echo Usage: $0 [-h] [-e env] [-v version] exit 0 ;; -e | --env) ENV$2 shift 2 ;; -v | --version) VERSION$2 shift 2 ;; *) echo Unknown option: $1 exit 1 ;; esac done这段脚本的精髓在于带值的参数比如-e prod消费两个位置参数用shift 2纯开关参数比如-h消费一个用shift。初学者容易漏掉shift 2里的数字结果参数错位解析出来的值全是乱的。更规范的写法是配合getopts它对短选项的解析能力更强甚至自动处理-e prod和-eprod两种写法但shift在解析长选项和复杂参数时依然不可替代。两者都掌握了写出来的脚本才能真正“像样”。6.2 type、alias、command搞清楚命令到底是什么“命令敲下去到底执行了什么”这个问题type能给出最直接的答案。type ls # ls is aliased to ls --colorauto type cd # cd is a shell builtin type curl # curl is /usr/bin/curl三种输出分别代表三类命令别名、Shell内建命令、外部命令。这个区别不是冷知识——排查脚本里“明明装了命令却找不到”的时候alias和外部命令的差异就是关键。有个很经典的坑非交互式Shell默认不加载~/.bashrc里定义的别名。脚本里用了ll这类别名但cron任务执行时根本没这个定义结果就是“手动跑正常一挂定时任务就报command not found”。想知道一个命令的真实路径还可以用command -v。它在脚本里比which更可靠因为command是Shell内建命令不依赖外部环境if command -v docker /dev/null 21; then echo docker is installed else echo docker not found fi这个写法在脚本里检查依赖项几乎是标准做法。6.3 脚本里常见的坑变量、引号与退出码最后是三个写脚本时最容易踩的坑每个都对应一条实际教训。第一个坑变量不加引号。for f in $files这行代码如果files变量里面包含一个带空格的文件名会被拆成两个值。正确的写法是for f in $files或者在收集文件列表时用数组files(*.log) for f in ${files[]}; do echo processing: $f done第二个坑退出码没有检查。Shell脚本默认“最后一条命令的退出码就是整个脚本的退出码”但如果你在中间某步失败了、又没检查$?后面的步骤可能基于错误前提继续执行。一个简单的防护是脚本开头加上set -e # 任一条命令失败脚本立即退出 set -u # 使用未定义的变量时报错生产脚本加set -euo pipefail已经成了共识。-o pipefail指的是管道中任意一条命令失败整个管道的状态就是失败的防止cmd1 | cmd2时cmd1悄悄失败但cmd2正常回包导致状态误判。第三个坑$和$*的行为差异。$把所有参数当成多个独立的字符串$*把所有参数当成一个字符串。循环遍历参数时必须用$用$*会把所有参数合并成一个字符串逐个处理的脚本就会出错。最后再分享一个小技巧。每次要批量操作很多文件不确定命令会不会误伤时先敲一个echo版本看输出for f in *.log; do echo rm -f $f; done输出确认无误再把echo去掉执行。这个习惯让我避免了好几次灾难性的误操作个人经验是在Shell里慢一拍比快一秒值钱得多。
返回列表