新闻详情

新闻详情

首页 / 资讯中心 / 详情

Linux终端特殊符号详解:从通配符到重定向与管道

发布时间:2026/10/1 21:47:58来源:尧图网络
Linux终端特殊符号详解:从通配符到重定向与管道
大概每个刚开始碰 Linux 终端的人都会经历这样的阶段一条命令看下来单词全认识但夹在里面的$、、、*、?这些符号让人一头雾水。我第一次执行find . -name *.log -mtime 7 -exec rm {} \;的时候根本不理解{}和\;是干什么的只能把整条命令当咒语背下来。后来专门把 shell 的符号体系过了一遍才真正从“抄命令”变成“写命令”。这篇东西不是命令大全而是特殊符号大全。我按使用场景把 Linux 终端里最常见的几类符号拆开讲通配符与路径展开、引号与转义、重定向与管道、变量与命令替换、历史命令符号、脚本逻辑符号以及终端里的控制字符。适合刚开始学 Linux 的新手也适合已经用了一段时间、遇到$(...)和${...}还要现查的老弟老妹。内容以 Bash 为准大部分结论在 Zsh 下也成立。1. 通配符与路径展开*、?、[]、{}、~、- 这些符号在动手前会先被展开1.1 路径展开~、-、.、.. 到底指哪里先记住一个底层概念shell 在执行命令之前会先做一堆“展开”动作。把~换成本用户的家目录把*换成匹配到的文件名把$(...)换成命令的输出结果。很多符号的坑都出在这个“先展开、后执行”的顺序上。~是最常见的路径符号。echo ~会直接输出当前用户的家目录路径比如/home/yourname。所以cd ~/Desktop等价于cd /home/yourname/Desktop。刚打开终端时pwd显示的就是家目录这也是提示符里出现~的原因。-代表“上一次所在目录”。cd -不是去上一级而是回到上一次 cd 之前的位置。假设你从/var/log切到/etc执行cd -就会跳回/var/log。连续执行两次cd -就会在两个目录之间反复横跳。改完配置想回工作目录时这个符号特别省事。.和..分别代表当前目录和上级目录。ls .查看当前内容cd ..回到上级目录cd ../..连续上跳两级。在find .这条命令里点号的意思就是“从当前目录开始递归查找”后面会经常见到。顺带把提示符也解释了。userhost:~$里的~表示当前目录在家里$表示当前是普通用户。如果提示符最后是#比如roothost:/etc#说明你正以 root 身份操作。看到$和#就要立刻反应过来权限上下文避免用错权限执行危险命令。1.2 通配符匹配*、?、[] 文件名的“模糊查询”shell 通配符用来匹配磁盘上已经存在的文件名不是正则表达式。很多新手把这两者混在一起后面会吃大亏。*匹配任意多个字符包括零个字符。ls *.txt列出所有以.txt结尾的文件rm -rf /tmp/backup-*删除/tmp下所有 backup- 开头的文件。注意它不会匹配以.开头的隐藏文件ls *永远看不到.bashrc这是刻意设计的安全机制免得rm *把配置文件一波带走。想匹配隐藏文件得显式写.bashrc或用ls -a。?匹配恰好一个字符。file?.log能匹配file1.log、fileA.log但匹配不了file10.log因为?只占一位。[ ]表示字符集合file[0-9].txt匹配file0.txt到file9.txt[abc]匹配 a、b、c 中任意一个[!0-9]表示“非数字”。写备份清理脚本时[0-9]{8}配合日期格式来筛文件是常规操作。千万别把通配符和正则混为一谈。正则里*表示“前一个字符重复任意次”^和$表示行首行尾这些概念和 shell 通配符完全是两码事。后面聊grep ^d时你会再看到^那是在正则语境里不是通配符。1.3 大括号展开{} 帮你生成批量清单大括号展开和通配符有本质区别通配符匹配已存在的文件大括号展开则单纯生成字符串列表才不管文件存不存在。echo {a,b,c}输出a b cecho {1..10}输出 1 到 10。更实用的用法是配合其他命令批量操作mkdir -p project/{src,bin,docs} cp app.log{,.bak}第二行等价于cp app.log app.log.bak这是复制日志文件做备份的经典简写。{a,b}{1,2}能组合出a1 a2 b1 b2嵌套、范围都可以自由组合。想要批量创建a.txt、b.txt、c.txt时touch {a..c}.txt一句顶三句。1.4 实战安全习惯先 echo 再执行 rm通配符展开发生在命令执行前一旦展开出意外路径列表删除操作不可逆。我自己的铁律是凡是带*的删除命令先跑一遍echo看展开结果。echo rm -rf *.log看到输出的文件列表符合预期再摘掉echo真正执行。也可以先用ls -l预览匹配结果。另外当目录里文件数量极大时通配符展开可能触发Argument list too long报错因为展开后的参数列表超过了系统 ARG_MAX 限制。这时不要硬刚通配符改用find /tmp -name *.log -delete或find ... | xargs rm -f更合适。2. 引号与转义、、\ 决定了变量和符号会不会被解析2.1 单引号 vs 双引号 vs 反斜杠三种“屏蔽”方式引号和转义的作用是让 shell 暂时停止解释特殊符号。但三者的屏蔽力度完全不同直接看对比表写法屏蔽级别$HOME会展开吗通配符会展开吗...全部屏蔽不会不会...部分屏蔽会不会\只屏蔽紧挨着的下一个字符看情况看情况单引号是“所见即所得”里面写什么就是什么。双引号则允许$、反引号和部分\继续工作但*、?这些通配符不会展开。最直观的例子echo $HOME echo $HOME第一行输出/home/user第二行输出$HOME。这就是区别。2.2 常见场景带空格文件名、变量拼接、通配符加引号处理带空格的文件名时引号和反斜杠都能解决问题cat my report.txt cat my\ report.txt两者等价都是让 shell 把my report.txt当成一个参数而不是拆成两个。我习惯用双引号视觉上更清晰。变量拼接是${}的主场。假设nameLinux想输出Linux的笔记.txtecho ${name}的笔记.txt如果不加大括号shell 会认为变量名叫name的笔记.txt结果啥也输出不了。双引号里的通配符不会展开echo *.txt输出字面的*.txt。特别容易踩坑的是ls *.txt这不是列出所有 txt 文件而是找文件名就叫*.txt的文件。在脚本里拼接路径时务必想清楚这个区别。2.3 反斜杠续行与 find -exec 的转义坑命令太长时行尾的\表示“命令还没完下一行继续”。注意\和换行之间不能有空格否则就不是续行而是转义空格。排版上的常规做法find /data \ -name *.log \ -mtime 7 \ -exec rm {} \;这个例子同时解释了find -exec里的转义问题。末尾的\;必须转义因为;如果裸露在外面会被 shell 当成命令分隔符find 直接语法报错。我第一次写脚本时把\;写成;报错排查了半天才意识到是转义问题。3. 重定向与管道、、、21、| 让命令之间互相传递数据3.1 先理解文件描述符0、1、2 分别代表什么Unix 哲学里“一切皆文件”每个进程默认有三个文件描述符0 是标准输入 stdin1 是标准输出 stdout2 是标准错误 stderr。重定向干的事情就是把这几个通道从默认的终端改接到文件或其他进程。很多教程直接抛和2的用法但如果不理解 0/1/2 的底层逻辑碰到21还是会懵。记住这三个编号后面全是推导式理解。3.2 输出重定向 、 与输入重定向 、heredoc是覆盖写。ls -l files.txt把输出写进文件文件若已存在会先被截断再写入这是不可逆操作。是追加写日志场景用得最多echo $(date) app.log。危险案例必须单独拎出来sort file.txt file.txt会得到一个空文件。原因是 shell 先执行重定向打开file.txt并清空然后 sort 读到的已经是空文件了。重定向的目标文件和输入文件绝不能是同一个。输入重定向的很简单wc -l /etc/passwd直接把文件内容喂给命令。更常用的是 heredoccat EOF config.txt keyvalue EOF后面跟定界符内容写到再次出现定界符为止。如果把EOF写成EOF内部的$HOME这类变量不会展开保持字面量这在生成配置模板时很实用。Bash 还支持here string比如grep foo $var直接把变量内容作为标准输入。3.3 错误重定向 2 与 21顺序写反了结果完全不同默认只接管标准输出错误信息还是会打到终端。看一个常见的清理场景find / -name *.conf 2/dev/null这里2/dev/null的作用是把错误信息丢进黑洞只保留正常结果。想要把正常输出和错误信息写进同一个文件写法有讲究command all.log 21顺序是先把标准输出指向 all.log再把标准错误复制到“标准输出当前指向的位置”也就是 all.log。如果反着写command 21 all.log先把标准错误复制到“标准输出当前指向的位置”此时还是终端再把标准输出指向 all.log。最后错误依然显示在终端。记忆口诀谁先指向终点谁就在终点。这个执行顺序问题面试经常被问实际排错时也容易踩。3.4 管道 | 与 tee从“写文件”到“接程序”|管道把左边命令的 stdout 直接接到右边命令的 stdin不是中间落盘再读而是实时流转ls -l | grep ^d ps aux | grep sshgrep ^d里的^是正则的行首锚点作用是只保留以d开头的行也就是目录条目。ps aux | grep ssh则是查进程的经典组合注意 grep 进程本身也可能出现在结果里嫌烦可以加| grep -v grep。和|的分工一个接文件、一个接命令。而tee能同时做到两者echo hello | tee file.txt输出显示在终端同时写入 file.txt。tee -a是追加模式。调试脚本时想一边看日志一边存档这个命令就是为此生的。4. 变量、命令替换与算术扩展$、${}、$()、$(( )) 是最容易搞混的一组4.1 $var 与 ${var}边界问题变量赋值语法是nameLinux注意等号两边不能有空格。读取变量时$name和${name}多数情况下等价但拼接场景立刻见分晓nameLinux echo ${name}的笔记.txt$name的笔记.txt会被解析成变量名name的笔记.txt结果为空。加上大括号明确边界输出才是Linux的笔记.txt。我的习惯是脚本里一律写${var}可读性更好也彻底避开这种边界陷阱。4.2 ${} 还能做默认值、字符串截断这组是写健壮脚本的利器。服务端口没设置时给个默认值PORT${PORT:8080} echo ${HOST:-localhost} echo ${DATABASE:?数据库地址未设置}:在变量为空时写入默认值:-只在本次表达式中用默认值但不用改变量本身:?在变量为空时直接报错退出非常适合脚本参数检查。以上第一行别漏了开头那个空命令:不然参数展开的结果会被当成命令执行而出错。字符串截断是处理文件名的基本功filearchive.tar.gz echo ${file%.*} # 输出去掉最短后缀的结果archive.tar echo ${file%%.*} # 去掉最长后缀archive echo ${file#*.} # 去掉最短前缀tar.gz echo ${file##*.} # 去掉最长前缀gz%从尾巴削#从开头削双写取最长匹配。注意这些 pattern 是通配符风格不是正则。4.3 $() 命令替换与反引号为什么我推荐用 $()命令替换的作用是把另一个命令的输出嵌入当前命令now$(date %F) echo 今天是 $now echo 当前目录有 $(ls -1 | wc -l) 个文件老式写法是反引号nowdate %F反引号没有消失但在需要嵌套时非常痛苦resultecho \date\这段代码的转义可读性极差。$()支持直接嵌套逻辑更清晰。我统一建议用$()新写的脚本里没必要再碰反引号。命令替换也有坑输出结尾的换行符会被吃掉输出内容过大时可能超出参数长度限制。更隐蔽的是退出码问题if value$(maybe_fail); then判断的是这条赋值语句整体的退出码如果想拿到里面命令的真实退出码应拆开写value$(maybe_fail) status$? echo $status4.4 $(( )) 算术扩展与 (( )) 的流程控制整数运算用$(( ))echo $((10 2 * 3)) i1 echo $((i 1))算术扩展里变量可以省略$$((i 1))没问题。还有一个不带美元号的(( ))主要用在流程控制。if (( i 10 ))的退出码取决于括号内表达式结果是否为非零(( 1 1 ))返回 0 表示真(( 0 ))返回 1 表示假。是不是有点绕多写几个条件脚本就习惯了。5. 历史命令里的符号捷径!!、!$、!^ 省去重复敲长命令5.1 基础history 与几个以 ! 开头的快捷引用终端会记录你敲过的命令history可以查看。围绕历史记录有一组以!开头的快捷引用纯键盘操作手都不用离开主键区符号含义!!上一条完整命令!$上一条命令的最后一个参数!^上一条命令的第一个参数!*上一条命令除命令名外的所有参数!n执行历史里的第 n 条命令!string执行最近一条以 string 开头的命令!?string执行最近一条包含 string 的命令history | grep之后用!数字直接执行特定命令也是常见组合。5.2 实战场景sudo !!、cd !$最常用的场景是忘写 sudoapt update # 提示权限不足 sudo !!!!展开成上一条命令sudo !!就是sudo apt update省得重敲一遍。!$在长路径场景里特别好用mkdir /data/tmp/backups/weekly cd !$第二行自动展开成cd /data/tmp/backups/weekly。先创建目录再进入目录一条!$搞定。!^则用于取上一条命令的第一个参数比如mv file1 file2之后想查看 file1用cat !^。5.3 注意历史扩展的坑与关闭方法历史扩展在非交互式 shell 里默认关闭脚本里写!!不会生效。交互终端里也有隐患如果你粘贴一段带!的文本比如一个含感叹号的密码!后面的内容可能被当成历史展开请求轻则展开成意外命令重则泄漏信息。遇到这种情况可以临时关闭历史扩展set H需要时再set -H恢复。不过日常写命令我还是更常按CtrlR做反向搜索对记忆模糊的长命令更友好。6. 脚本逻辑与位置参数#、;、、||、、!、$?、$ 让命令学会“判断”6.1 # 注释与提示符里的 root 标识脚本里的#是注释符号#后面的内容不执行。还有个特殊变体是脚本第一行的#!/bin/bash也就是 shebang告诉内核该用什么解释器执行这个脚本#!/bin/bash # 这是注释 echo hi#在脚本里是注释但在上一篇讲过的终端提示符里表示 root 身份。同样一个字符含义完全由上下文决定这也是理解 shell 的关键思维符号本身没有固定意义要看它出现在什么语境里。6.2 顺序执行 ; 与短路逻辑 、||三个符号的语义区别很清晰;按顺序执行前一条成败都拦不住后一条前一条成功才执行后一条||前一条失败才执行后一条实际用法make make install grep -q error app.log || echo 没有错误 cd /tmp || exit 1grep -q成功返回 0失败返回非 0所以|| echo表示“没匹配到就提示”。这是把退出码和逻辑判断结合起来的典型写法。圆括号( ... )用来分组并开启子 shell。(cd /tmp ls)在子 shell 里切换目录不会改变当前 shell 的工作目录。如果你不想让 cd 影响当前脚本上下文用圆括号包起来是安全做法。6.3 后台任务 、退出码 $?、取反 !命令结尾加让任务后台运行sleep 100 终端立刻返回提示符。用jobs查看后台任务kill %1杀掉第一个后台任务。%1是作业号引用%在作业控制里专门用来引用作业编号。$?保存上一条命令的退出码0 表示成功非 0 表示失败ls /no/such/path echo $?条件里的!是逻辑取反if ! grep -q error app.log; then echo 没有错误 fiif ! command就是“命令失败时才执行”。这个!和上一章历史扩展的!!完全是两码事别搞混。$$是当前 shell 的 PID$!是最近一个后台进程的 PID。写临时文件时经常用$$做后缀避免重名冲突。6.4 位置参数 $0、$1、$#、$脚本入口的“数据接口”写脚本必然要处理参数。位置参数的含义$0脚本名$1、$2第一个、第二个参数$#参数个数$所有参数每个作为独立词$*所有参数作为一个整体词写个小脚本验证#!/bin/bash echo 脚本名: $0 echo 参数个数: $# for arg in $; do echo 参数: $arg done保存为args.sh执行bash args.sh a b c输出一目了然。$和$*在参数包含空格时差异明显遍历参数用$更安全。6.5 组合示例一个带参数检查的备份脚本把这一章的符号组合起来写一个实用小脚本#!/bin/bash set -e BACKUP_DIR${1:?请指定备份目录} DESTbackup_$(date %F).tar.gz tar -czf $DEST $BACKUP_DIR echo 备份完成: $DEST || echo 备份失败第一行set -e让脚本在出错时立即退出。${1:?请指定备份目录}在没有传参时直接报错并退出这就是参数检查的简洁写法。$(date %F)生成日期字符串拼进备份文件名和||处理成功和失败两个分支。一个十几行的脚本里符号占了半壁江山但它们各司其职并不神秘。7. 终端显示里的控制字符^C、^D、^Z、^L 这些“脱字符组合”代表什么7.1 按下去的 Ctrl 键为什么显示成了 ^在终端里按CtrlC屏幕上会回显^C。这个^是 control 的缩写记号意思是“这个字符由 Ctrl 组合键产生”跟 shell 和正则里的^没有关系。很多新手看到^C以为是自己输错了字符其实这是中断信号用来终止当前正在运行的进程。7.2 常用控制字符逐个拆解按键终端显示作用CtrlC^C发送 SIGINT中断当前进程CtrlZ^Z发送 SIGTSTP挂起当前进程CtrlD^D发送 EOF退出当前输入连续按可退出 shellCtrlL无清屏清屏等效clearCtrlA无光标移到行首CtrlE无光标移到行尾CtrlW无删除光标前一个单词CtrlU无删除光标到行首的全部内容CtrlK无删除光标到行尾的全部内容CtrlR无反向搜索历史命令CtrlZ和CtrlC经常被新手混用。CtrlC是终止进程CtrlZ只是把进程挂起进程还在内存里可以用fg调回来继续跑jobs能查看挂起任务列表。7.3 stty -a 看终端键位映射stty -a输出当前终端驱动设置里面能看到intr ^C; eof ^D; susp ^Z; erase ^?这样的条目。erase ^?表示退格键产生的控制字符。如果某个快捷键突然失灵先看看stty -a的映射是否被改过。stty修改的是当前终端的驱动设置操作有风险不建议乱试。最后说句题外话。很多人学终端的时候习惯背命令我倒觉得先把符号体系过一遍后面遇到什么命令都能猜个七八分。命令会变但 shell 这套符号语法几十年没有大变花一个下午弄懂它们比背一百条命令更值。以后在别人的博客里看到21、${var:-def}、!!这类写法至少不会一头雾水。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Pogo Pin压缩裕量分析:用Python揪出多针阵列风险针位 2026/10/1 22:39:59

Pogo Pin压缩裕量分析:用Python揪出多针阵列风险针位

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Flutter牵手Apple Watch:跨端桥接实战与架构解析 2026/10/1 22:39:59

Flutter牵手Apple Watch:跨端桥接实战与架构解析

如果你手里有一块 Apple Watch,想在上面跑一个用 Flutter 写的交互界面,我猜你大概率会先去 pub.dev 搜一圈 watchOS 相关的包,然后发现官方压根没有支持。这个项目其实挺有意思的:Flutter 的跨端优势在手机和平板上确实香&#x…

阅读更多 →
Home Assistant 内网穿透:frp、ngrok 远程访问与安全加固 2026/10/1 22:39:58

Home Assistant 内网穿透:frp、ngrok 远程访问与安全加固

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
openGauss Summit 2025:存储过程增强与AI自治,破解数据库瓶颈 2026/10/1 22:39:52

openGauss Summit 2025:存储过程增强与AI自治,破解数据库瓶颈

1. 数智时代数据库的瓶颈与openGauss Summit 2025的看点1.1 为什么openGauss Summit 2025值得关注做数据库相关工作的人,这两年最大的感受应该是:过去拼的是单机性能,现在拼的是“整个数据基础设施能不能跟上业务变化”。尤其当AI大模型、实时…

阅读更多 →
Zabbix邮件报警配置与排错:SMTP、媒介类型、动作和降噪 2026/10/1 22:39:52

Zabbix邮件报警配置与排错:SMTP、媒介类型、动作和降噪

做运维这行,监控搭起来只是第一步,真正让人半夜从床上弹起来的,永远是那条没发出去的报警。我见过太多环境,Zabbix 的图做得漂漂亮亮,触发器写得严丝合缝,结果主机真挂了,收件箱里一篇寂静——问…

阅读更多 →
超构表面远场偏振态分析:动量空间C/V点提取与后处理全流程 2026/10/1 22:39:45

超构表面远场偏振态分析:动量空间C/V点提取与后处理全流程

超构表面的远场偏振态分析,这几年在纳米光子学里是真的热。不管是超表面透镜、偏振转换器还是谷光子学器件,大家最终都要回答一个核心问题:我设计的结构,在动量空间(也就是远场辐射的k矢量空间)里&#xff…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉