Linux(CentOS)系统管理入门笔记(第六期)——Shell 交互核心:重定向、管道、变量与环境配置

Linux(CentOS)系统管理入门笔记(第六期)——Shell 交互核心:重定向、管道、变量与环境配置

Linux系统管理入门系列其他文章欢迎访问:Linux入门——系统管理1

我的主页:AOwhisky,这里有更多运维系统性知识整理和其他有趣内容,欢迎与我一起探讨学习~

引言:让命令行“流动”起来——输入、输出与变量

前五期我们学会了在 Linux 文件系统中“行走”、操作文件、查阅文档和编辑文本。但你有没有注意到一个现象:每次执行命令,结果都直接“喷”到屏幕上。如果我想把结果保存下来呢?如果我只想看成功的输出、忽略错误信息呢?如果我想把命令 A 的输出直接喂给命令 B 处理呢?

这就是本期要解决的三个核心问题——重定向(Redirection) 控制数据流向,管道(Pipe) 让命令串联协作,变量(Variable) 让命令行变得更智能、更可复用。

想象一下:你是一家快递分拣中心的调度员。包裹(数据)从各个入口涌进来。你可以决定:

  • 把某些包裹送去仓库 A> 输出到文件)
  • 把某些包裹直接扔进碎纸机2>/dev/null 丢弃错误)
  • 把包裹从传送带 A 直接搬到传送带 B| 管道传递)
  • 甚至给每个包裹贴上一个标签(变量存储),方便后续识别和处理

本期我们将系统学习:

  • 标准输出与错误输出重定向>>>2>&>
  • 管道 |tee 命令——一边输出一边保存
  • 标准输入重定向<<<
  • Shell 变量的定义、引用、作用域
  • 环境变量PATHPS1LANGEDITOR)的配置与持久化
  • 命令替换$() 和反引号)与引号/转义的精确控制

读完这一期,你将真正理解 Shell 的“数据流哲学”——让命令不再是孤立的工具,而是一个可组合、可编程的工作流系统。

— Compiled and Authored by Whisky — July 13 th, 2026

目录

  1. 标准输出重定向:>>>
  2. 标准错误重定向:2> 与合并重定向
  3. 管道 |:命令协作的“传送带”
  4. tee:分流输出到文件与屏幕
  5. 标准输入重定向:<<<
  6. Shell 变量:定义、引用与作用域
  7. 环境变量:系统的“全局配置”
  8. 命令替换与引号控制
  9. 总结与速查手册

1. 标准输出重定向:>>>

1.1 三个标准数据流

Linux 中每个进程启动时,系统会自动为其打开三个数据通道:

通道文件描述符默认去向用途
标准输入(stdin)0键盘程序读取输入数据
标准输出(stdout)1屏幕程序输出正常结果
标准错误(stderr)2屏幕程序输出错误信息

重定向的本质:将某个数据流从默认位置(屏幕/键盘)改道到文件或其他地方。

1.2 > —— 覆盖写入

# 查找 /etc 下所有名为 passwd 的文件
[whisky@centos7 ~]$ find /etc -name 'passwd'
find: ‘/etc/pki/CA/private’: 权限不够
find: ‘/etc/pki/rsyslog’: 权限不够
/etc/pam.d/passwd
/etc/passwd
find: ‘/etc/dhcp’: 权限不够
...

# 将标准输出(正确结果)重定向到文件
[whisky@centos7 ~]$ find /etc -name 'passwd' > passwd.list
find: ‘/etc/pki/CA/private’: 权限不够  # 错误信息仍显示在屏幕
...

[whisky@centos7 ~]$ cat passwd.list
/etc/pam.d/passwd
/etc/passwd
基本用法
# 1> 可简写为 >
# 注意:1 和 > 之间不能有空格
[whisky@centos7 ~]$ find /etc -name 'passwd' 1> passwd.list   # 等价于 > passwd.list

# 将多个文件内容合并为一个文件
[whisky@centos7 ~]$ cat /etc/fstab /etc/hosts > allinone
[whisky@centos7 ~]$ cat allinone
# 包含 fstab 和 hosts 的全部内容

1.3 >> —— 追加写入

> 会覆盖目标文件,>>追加到文件末尾:

[whisky@centos7 ~]$ echo "第一次写入" > test.log
[whisky@centos7 ~]$ cat test.log
第一次写入

[whisky@centos7 ~]$ echo "第二次写入" >> test.log
[whisky@centos7 ~]$ cat test.log
第一次写入
第二次写入

# 再次执行 > 会覆盖原有内容
[whisky@centos7 ~]$ echo "覆盖写入" > test.log
[whisky@centos7 ~]$ cat test.log
覆盖写入

1.4 创建空文件或清空文件

# 用 > 创建空文件(文件不存在则创建,存在则清空)
[whisky@centos7 ~]$ > empty.log
[whisky@centos7 ~]$ ls -l empty.log
-rw-rw-r--. 1 whisky whisky 0 713 15:30 empty.log

# >> 也可以创建空文件(但不如 > 直观)
[whisky@centos7 ~]$ >> empty2.log

💡 最佳实践:用 > /path/to/file 清空日志文件比 rm 后重建更安全——文件权限和所有者保持不变。

2. 标准错误重定向:2> 与合并重定向

2.1 2> —— 重定向错误信息

上面的 find 示例中,权限错误信息依然显示在屏幕上。用 2> 可以将错误单独存放:

# 将错误信息写入 err.log,标准输出仍显示在屏幕
[whisky@centos7 ~]$ find /etc -name 'passwd' 2> passwd.err
/etc/pam.d/passwd
/etc/passwd

[whisky@centos7 ~]$ cat passwd.err
find: ‘/etc/pki/CA/private’: 权限不够
find: ‘/etc/pki/rsyslog’: 权限不够
find: ‘/etc/grub.d’: 权限不够
...

2.2 输出与错误分开存放

# 标准输出 → passwd.list,标准错误 → passwd.err
[whisky@centos7 ~]$ find /etc -name 'passwd' > passwd.list 2> passwd.err

[whisky@centos7 ~]$ cat passwd.list
/etc/pam.d/passwd
/etc/passwd

[whisky@centos7 ~]$ cat passwd.err
find: ‘/etc/pki/CA/private’: 权限不够
find: ‘/etc/pki/rsyslog’: 权限不够
...

2.3 丢弃错误信息:2>/dev/null

/dev/null 是 Linux 的“黑洞”——任何写入它的数据都会被丢弃。这在生产环境中非常实用:

# 只显示正确结果,隐藏所有错误
[whisky@centos7 ~]$ find /etc -name 'passwd' 2>/dev/null
/etc/pam.d/passwd
/etc/passwd

# 什么也不显示(正确结果和错误都丢弃)
[whisky@centos7 ~]$ find /etc -name 'passwd' >/dev/null 2>&1
# 无输出(稍后解释 2>&1)

⚠️ 常见误区2>/dev/null 不是“没有错误”,而是“错误被扔掉了”。调试时慎用,建议先用 2> err.log 查看错误内容,确定无影响再丢弃。

2.4 合并重定向:&>2>&1

将标准输出和标准错误合并到同一个文件

# 方法一:&>(简洁写法,推荐)
[whisky@centos7 ~]$ find /etc -name 'passwd' &> passwd.all
[whisky@centos7 ~]$ cat passwd.all
/etc/pam.d/passwd
/etc/passwd
find: ‘/etc/pki/CA/private’: 权限不够
...

# 方法二:2>&1(经典写法,兼容性更好)
[whisky@centos7 ~]$ find /etc -name 'passwd' > passwd.all 2>&1
# 效果同上

# 追加模式
[whisky@centos7 ~]$ find /etc -name 'passwd' &>> passwd.all
# 或
[whisky@centos7 ~]$ find /etc -name 'passwd' >> passwd.all 2>&1

💡 理解 2>&12>&1 的意思是“将文件描述符 2(标准错误)重定向到文件描述符 1(标准输出)当前指向的位置”。必须先有 >>> 确定了标准输出的去向,2>&1 才能跟随。

2.5 重定向操作符速查表

操作符含义示例
>1>覆盖标准输出到文件ls > list.txt
>>1>>追加标准输出到文件ls >> list.txt
2>覆盖标准错误到文件cmd 2> err.log
2>>追加标准错误到文件cmd 2>> err.log
&>合并输出和错误(覆盖)cmd &> all.log
&>>合并输出和错误(追加)cmd &>> all.log
2>&1将错误重定向到输出的去向cmd > out 2>&1
>/dev/null 2>&1丢弃所有输出后台静默运行

3. 管道 |:命令协作的“传送带”

3.1 管道的基本概念

管道符 | 的作用是:将前一个命令的标准输出,作为后一个命令的标准输入

cmd1 | cmd2 | cmd3

数据流向:cmd1 的屏幕输出 → cmd2 的键盘输入 → cmd2 的输出 → cmd3 的输入

3.2 基础示例

# 查找 ext4 相关的 man 手册,然后筛选出包含 "resizer" 的行
[whisky@centos7 ~]$ man -k ext4 | grep resizer
resize2fs (8)        - ext2/ext3/ext4 file system resizer

# 查看系统进程,筛选出 bash 相关
[whisky@centos7 ~]$ ps -ef | grep bash
whisky     2843  2840  0 10:16 pts/1    00:00:00 -bash
whisky     3356  3348  0 10:36 tty2     00:00:00 /bin/bash
root      4820  2816  0 11:23 pts/0    00:00:00 grep --color=auto bash

# 统计 /etc 目录下有多少个文件
[whisky@centos7 ~]$ ls /etc | wc -l
256

# 找出当前目录下最大的 5 个文件
[whisky@centos7 ~]$ ls -lS | head -5

3.3 管道与重定向的组合

# 将搜索到的 ext4 手册保存到文件,同时筛选
[whisky@centos7 ~]$ man -k ext4 > ext4.man
[whisky@centos7 ~]$ grep resizer ext4.man

# 等价写法(管道 + 重定向)
[whisky@centos7 ~]$ man -k ext4 | grep resizer > result.txt

3.4 ⚠️ 管道的常见误区

并非所有命令都能接收管道输入。 管道传递的是标准输入(stdin),但有些命令(如 lsrmcp不读取标准输入,它们从命令行参数获取目标。

# ❌ 错误:ls 不读取 stdin,管道数据被忽略
[whisky@centos7 ~]$ echo /etc | ls -l
# 等价于 ls -l,显示当前目录内容

# ✅ 正确:xargs 将 stdin 转换为命令行参数
[whisky@centos7 ~]$ echo /etc | xargs ls -l
# 显示 /etc 目录的内容

# 常用组合:find + xargs 处理大量文件
[whisky@centos7 ~]$ find . -name "*.log" | xargs rm -f

3.5 |&:同时传递错误和输出

|& 是将标准错误也一并传递给下一个命令(类似于 2>&1 |):

# 只有标准输出能通过管道
[whisky@centos7 ~]$ ls -l file-{01..06} | grep file-06
ls: cannot access 'file-04': No such file or directory
ls: cannot access 'file-05': No such file or directory
ls: cannot access 'file-06': No such file or directory
# grep 没有匹配(因为它收到的输入中不包含错误信息)

# |& 将错误也传递给 grep
[whisky@centos7 ~]$ ls -l file-{01..06} |& grep file-06
ls: cannot access 'file-06': No such file or directory

4. tee:分流输出到文件与屏幕

4.1 为什么需要 tee?

管道让命令串联,但如果同时想在屏幕上看到输出,又保存到文件呢?单纯用 > 重定向会看不到屏幕输出,单纯用 | 传递给下一个命令也看不到中间结果。

tee 命令解决了这个问题——它从标准输入读取数据,然后同时输出到标准输出(屏幕)和文件

4.2 基本用法

# 查找 passwd 文件,同时显示在屏幕并保存到文件
[whisky@centos7 ~]$ find /etc -name 'passwd' 2>/dev/null | tee passwd.list
/etc/pam.d/passwd   # ← 显示在屏幕
/etc/passwd         # ← 显示在屏幕

[whisky@centos7 ~]$ cat passwd.list
/etc/pam.d/passwd
/etc/passwd

4.3 追加模式:-a

# 第一次执行,覆盖写入
[whisky@centos7 ~]$ find /etc -name 'passwd' 2>/dev/null | tee passwd.list
/etc/pam.d/passwd
/etc/passwd

# 第二次执行,追加写入(-a)
[whisky@centos7 ~]$ find /etc -name 'passwd' 2>/dev/null | tee -a passwd.list
/etc/pam.d/passwd
/etc/passwd

[whisky@centos7 ~]$ cat passwd.list
/etc/pam.d/passwd
/etc/passwd
/etc/pam.d/passwd
/etc/passwd

4.4 tee 在管道链中的位置

tee 可以放在管道链的中间,既保存中间结果,又继续向下传递:

# 查找 passwd 相关手册 → 保存到文件 → 同时过滤出 "passwd" 行
[whisky@centos7 ~]$ man -k passwd | tee passwd.man | grep passwd
# 屏幕显示的是过滤后的结果
# passwd.man 保存了完整的 man -k 输出

4.5 tee 典型应用场景

场景示例
安装日志留存`yum install httpd
调试管道链`cmd1
脚本执行记录`./deploy.sh 2>&1

5. 标准输入重定向:<<<

5.1 < —— 从文件读取输入

默认情况下,命令从键盘(标准输入)读取数据。用 < 可以从文件读取:

# cat 默认从键盘读取输入(按 Ctrl+D 结束)
[whisky@centos7 ~]$ cat
hello
hello
world
world
# 按 Ctrl+D 退出

# 用 < 从文件读取输入
[whisky@centos7 ~]$ cat < /etc/hosts
127.0.0.1   localhost localhost.localdomain ...
::1         localhost localhost.localdomain ...
# 效果与 cat /etc/hosts 相同(但机制不同)

区别

  • cat /etc/hosts/etc/hosts 是命令行参数,cat 主动打开文件
  • cat < /etc/hosts:Shell 打开文件,将内容作为标准输入传给 cat

对于 cat,两者效果相同。但测试一个命令是否接收标准输入,可以用 < 验证:

# ls 不接收标准输入,输入重定向无效
[whisky@centos7 ~]$ ls < /etc/hosts
# 仍然显示当前目录内容

# wc 接收标准输入
[whisky@centos7 ~]$ wc -l < /etc/hosts
3

5.2 << —— Here Document(内联输入)

<< 允许在命令行中直接指定多行输入,以特定字符串(如 EOF)结束:

# 基本语法:cat << EOF
[whisky@centos7 ~]$ cat << EOF
> 第一行
> 第二行
> 第三行
> EOF
第一行
第二行
第三行

5.3 实战:一次性写入多行内容到文件

# 方法一:用 echo 加引号(简单场景)
[whisky@centos7 ~]$ echo '第一行
> 第二行
> 第三行' > multi.txt

# 方法二:用 cat + Here Document(推荐,更清晰)
[whisky@centos7 ~]$ cat > config.conf << EOF
# 这是配置文件
DATABASE_HOST=localhost
DATABASE_PORT=3306
DATABASE_USER=admin
EOF

[whisky@centos7 ~]$ cat config.conf
# 这是配置文件
DATABASE_HOST=localhost
DATABASE_PORT=3306
DATABASE_USER=admin

💡 最佳实践:在 Shell 脚本中用 Here Document 生成配置文件,代码清晰且易于维护。

5.4 输入重定向操作符速查

操作符名称作用
<输入重定向从文件读取输入
<<Here Document从命令行内联读取多行输入
<<<Here String从字符串读取输入(Bash 扩展)
# <<< 示例(将字符串作为标准输入)
[whisky@centos7 ~]$ wc -w <<< "hello world"
2

6. Shell 变量:定义、引用与作用域

6.1 变量的定义与命名

Shell 变量是存储在内存中的键值对,用于保存临时数据。

变量名规则

  • 只能包含字母、数字、下划线
  • 不能以数字开头
  • 区分大小写(nameNAME
# 定义变量(等号两边不能有空格!)
[whisky@centos7 ~]$ username=facai
[whisky@centos7 ~]$ first_name=zhang
[whisky@centos7 ~]$ var1=hello123

# ❌ 错误示例
[whisky@centos7 ~]$ 1var=hello    # 不能以数字开头
[whisky@centos7 ~]$ user name=facai  # 不能有空格
[whisky@centos7 ~]$ user-name=facai  # 不能有连字符

6.2 引用变量值:$

[whisky@centos7 ~]$ first_name=zhang
[whisky@centos7 ~]$ last_name=facai

# 引用变量
[whisky@centos7 ~]$ echo $last_name $first_name
zhang facai

# 字符串拼接
[whisky@centos7 ~]$ echo $last_name-$first_name
zhang-facai

6.3 变量边界:${}

当变量名与其他字符连在一起时,用 ${} 明确边界:

[whisky@centos7 ~]$ last_name=zhang
[whisky@centos7 ~]$ first_name=facai

# 错误:Shell 会寻找变量 last_name_(不存在)
[whisky@centos7 ~]$ echo $last_name_$first_name
facai

# 正确:用 {} 明确边界
[whisky@centos7 ~]$ echo ${last_name}_$first_name
zhang_facai

6.4 查看与删除变量

# set 显示所有变量(包括环境变量和函数)
[whisky@centos7 ~]$ set | grep first_name
first_name=facai

# unset 删除变量
[whisky@centos7 ~]$ unset first_name
[whisky@centos7 ~]$ echo $first_name
# 无输出

6.5 变量作用域:export

变量默认是局部变量,只在当前 Shell 中有效。子 Shell(如执行 bash 后)无法看到父 Shell 的局部变量:

[whisky@centos7 ~]$ username=tom
[whisky@centos7 ~]$ echo $username
tom

[whisky@centos7 ~]$ bash   # 进入子 Shell
[whisky@centos7 ~]$ echo $username
# 无输出(局部变量不可见)
[whisky@centos7 ~]$ exit   # 退出子 Shell

# 使用 export 将变量提升为全局(环境变量)
[whisky@centos7 ~]$ export username=tom
# 或分两步
[whisky@centos7 ~]$ username=tom
[whisky@centos7 ~]$ export username

[whisky@centos7 ~]$ bash   # 进入子 Shell
[whisky@centos7 ~]$ echo $username
tom                       # 现在可见了

6.6 变量类型修饰(declare

# declare 显式声明变量
[whisky@centos7 ~]$ declare var1=key1

# -l:强制转为小写
[whisky@centos7 ~]$ declare -l name=James
[whisky@centos7 ~]$ echo $name
james

# -u:强制转为大写
[whisky@centos7 ~]$ declare -u name=James
[whisky@centos7 ~]$ echo $name
JAMES

# -i:声明为整数
[whisky@centos7 ~]$ declare -i num=10+5
[whisky@centos7 ~]$ echo $num
15

7. 环境变量:系统的“全局配置”

7.1 什么是环境变量

环境变量是系统预设或用户设置的全局变量,影响 Shell 的行为和程序的运行环境。用 envprintenv 查看所有环境变量:

[whisky@centos7 ~]$ env
USER=whisky
HOME=/home/whisky
SHELL=/bin/bash
LANG=zh_CN.utf8
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/whisky/.local/bin:/home/whisky/bin
PWD=/home/whisky
...

7.2 核心环境变量详解

PATH —— 命令搜索路径

PATH 决定了输入命令时,Shell 去哪些目录查找可执行文件:

[whisky@centos7 ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/whisky/.local/bin:/home/whisky/bin

# 查找命令位置
[whisky@centos7 ~]$ which ls
alias ls='ls --color=auto'
    /usr/bin/ls

修改 PATH(临时)

# 追加一个目录到 PATH 末尾
[whisky@centos7 ~]$ export PATH=$PATH:/home/whisky/bin

# 添加一个目录到 PATH 开头(优先级更高)
[whisky@centos7 ~]$ export PATH=/home/whisky/bin:$PATH

⚠️ 常见问题:执行自己写的脚本报 command not found,原因往往是脚本目录不在 PATH 中。解决方案:用绝对路径执行(/home/user/script.sh),或将脚本目录加入 PATH

LANG —— 系统语言
[whisky@centos7 ~]$ echo $LANG
zh_CN.utf8

[whisky@centos7 ~]$ date
2026713日 星期一 15:30:00 CST

# 临时切换语言
[whisky@centos7 ~]$ export LANG=en_US.utf8
[whisky@centos7 ~]$ date
Mon Jul 13 15:30:05 CST 2026
语言代码含义
en_US.utf8英语(美国),UTF-8 编码
zh_CN.utf8简体中文,UTF-8 编码
zh_TW.utf8繁体中文,UTF-8 编码
EDITOR —— 默认编辑器

许多命令(如 visudocrontab -e)会使用 EDITOR 环境变量指定的编辑器:

[root@centos7 ~]# visudo
# 默认使用 vi

[root@centos7 ~]# export EDITOR=/bin/vim
[root@centos7 ~]# visudo
# 现在使用 vim(有语法高亮)
PS1 —— 命令提示符

PS1 定义了命令提示符的样式:

[whisky@centos7 ~]$ echo $PS1
[\u@\h \W]\$

# 修改提示符
[whisky@centos7 ~]$ PS1='HELLO > '
HELLO > echo hello
hello

# 恢复默认
[whisky@centos7 ~]$ PS1='[\u@\h \W]\$ '

PS1 常用转义字符

转义含义
\u当前用户名
\h主机名(第一个 . 之前)
\H完整主机名
\w完整工作目录
\W工作目录的基名(最后一层)
\t当前时间(24 小时制 HH:MM:SS)
\$#(root)或 $(普通用户)

彩色提示符示例

# 绿色用户名 + 青色目录
[whisky@centos7 ~]$ PS1='\[\e[0;32m\]\u\[\e[0m\]@\[\e[0;32m\]\h\[\e[0m\]:\[\e[0;34m\]\W\[\e[0m\]\$ '
# 效果:绿色用户名@绿色主机名:蓝色目录$

7.3 环境变量持久化

临时用 export 设置的变量只在当前会话有效。重启或新开终端后失效。

要让变量永久生效,需写入配置文件:

配置文件作用范围加载时机用途
/etc/profile所有用户登录 Shell 启动时系统级全局配置
~/.bash_profile当前用户登录 Shell 启动时用户个人配置
~/.bashrc当前用户非登录 Shell 启动时用户个人配置(别名、函数)
/etc/bashrc所有用户非登录 Shell 启动时系统级 Shell 配置
# 示例:为所有用户设置英文环境
[root@centos7 ~]# echo 'export LANG=en_US.utf8' >> /etc/profile

# 示例:为当前用户设置 EDITOR
[whisky@centos7 ~]$ echo 'export EDITOR=vim' >> ~/.bashrc

# 示例:添加自定义脚本目录到 PATH
[whisky@centos7 ~]$ echo 'export PATH=$PATH:/home/whisky/scripts' >> ~/.bash_profile

7.4 环境变量速查表

变量含义常见值
PATH命令搜索路径冒号分隔的目录列表
HOME当前用户家目录/home/username
USER当前用户名whisky
SHELL当前 Shell 路径/bin/bash
PWD当前工作目录/home/whisky
LANG系统语言zh_CN.utf8 / en_US.utf8
EDITOR默认编辑器vim / nano
PS1命令提示符样式[\u@\h \W]\$
HISTFILE历史文件路径~/.bash_history
HISTSIZE历史命令条数1000

8. 命令替换与引号控制

8.1 命令替换:$() 与反引号

命令替换允许将命令的输出作为另一个命令的参数或赋值给变量。

# 两种语法
$(COMMAND)   # 推荐(可嵌套)
`COMMAND`    # 旧语法(不推荐嵌套)
# 示例:用 date 生成文件名
[whisky@centos7 ~]$ touch file-$(date +%Y%m%d).txt
[whisky@centos7 ~]$ ls file-*
file-20260713.txt

# 示例:将命令结果赋值给变量
[whisky@centos7 ~]$ today=$(date +%A)
[whisky@centos7 ~]$ echo "今天星期 $today"
今天星期一

# 示例:嵌套命令替换($() 支持嵌套)
[whisky@centos7 ~]$ echo "当前目录有 $(ls | wc -l) 个文件"
当前目录有 42 个文件

# 反引号不支持嵌套(容易混淆)
[whisky@centos7 ~]$ echo `echo \`date\``  # 复杂且易错

8.2 引号与转义:保留字符的字面含义

许多字符在 Shell 中有特殊含义(如 $ 表示变量、* 表示通配符、空格分隔参数)。用引号和转义可以取消这些特殊含义

方式作用范围是否展开变量是否展开命令替换
反斜杠 \仅下一个字符
双引号 ""整个字符串
单引号 ''整个字符串
\ —— 转义单个字符
[whisky@centos7 ~]$ echo \$PATH
$PATH

[whisky@centos7 ~]$ echo "文件名是: file\ with\ space.txt"
文件名是: file with space.txt
"" —— 弱引用(保留变量和命令替换)
[whisky@centos7 ~]$ username=alice
[whisky@centos7 ~]$ echo "欢迎 $username,今天是 $(date +%F)"
欢迎 alice,今天是 2026-07-13

# 特殊字符如 $ 仍需转义
[whisky@centos7 ~]$ echo "价格是 \$100"
价格是 $100
'' —— 强引用(完全字面量)
[whisky@centos7 ~]$ username=alice
[whisky@centos7 ~]$ echo '欢迎 $username,今天是 $(date +%F)'
欢迎 $username,今天是 $(date +%F)
# 变量和命令替换都没有展开!

# 单引号内不能包含单引号
[whisky@centos7 ~]$ echo 'Let\'s go'
>  # 错误!需要用双引号或转义
[whisky@centos7 ~]$ echo "Let's go"
Let's go

8.3 保留空白字符

Shell 默认将多个空格、Tab 压缩为单个空格分隔符。用引号可以保留:

[whisky@centos7 ~]$ echo hello     world
hello world

[whisky@centos7 ~]$ echo "hello     world"
hello     world

8.4 引号与转义实战总结

场景写法说明
文件名有空格cd "My Documents"双引号包裹
变量值中有特殊字符echo "$USER"双引号保留变量展开
输出纯文本中的 $echo '价格是 $100'单引号让 $ 失去特殊含义
输出包含单引号echo "It's OK"双引号内含单引号
在变量中等号后有空格msg="hello world"不加引号会报错
命令替换file-$(date +%Y%m%d)推荐 $()

9. 总结与速查手册

9.1 核心知识点一览

主题关键点
标准输出重定向> 覆盖,>> 追加
标准错误重定向2> 单独重定向错误,2>&1 合并
丢弃输出2>/dev/null 丢弃错误,&>/dev/null 全部丢弃
**管道 ``**
tee同时输出到屏幕和文件(-a 追加)
标准输入重定向< 从文件读,<< Here Document
变量变量名=值$变量名 引用,export 提升为环境变量
环境变量PATH(命令路径)、LANG(语言)、PS1(提示符)
命令替换$(command) 或反引号
引号\ 转义单字符,"" 保留变量展开,'' 完全字面

9.2 重定向速查表

操作符含义
>标准输出覆盖到文件
>>标准输出追加到文件
2>标准错误覆盖到文件
2>>标准错误追加到文件
&>覆盖合并输出和错误
&>>追加合并输出和错误
2>&1将错误重定向到标准输出
> file 2>&1合并输出和错误到 file
2>/dev/null丢弃错误信息

9.3 管道与 tee 速查表

操作符作用
`cmd1cmd2`
`cmd1& cmd2`
`cmdtee file`
`cmdtee -a file`

9.4 变量与环境变量速查表

操作语法
定义变量var=value(等号两边无空格)
引用变量$var${var}
查看所有变量set
删除变量unset var
提升为环境变量export varexport var=value
查看环境变量envprintenv
修改 PATHexport PATH=$PATH:/新/目录

9.5 命令替换与引号速查表

操作语法
命令替换$(command)command
转义单字符\
弱引用(展开变量)"字符串"
强引用(不展开)'字符串'

9.6 常见错误排查指南

错误现象原因解决方案
command not found命令不在 PATH 中用绝对路径执行,或将目录加入 PATH
> file 后屏幕还在输出是错误信息(stderr)2>&> 合并重定向
变量赋值报错 command not found等号两边有空格移除空格:var=value
echo $var 显示为空变量未定义或作用域不对用 `set
echo $PATH 后目录重复重复追加 PATH检查 .bashrc 中是否有重复的 export
单引号内无法展开变量单引号不展开任何内容改用双引号 "$var"
文件名含空格无法操作未加引号用引号包裹:"file name.txt"
cat << EOF 报错EOF 前有空格或 TabEOF 必须顶格写(行首)

9.7 综合实战:数据流组合拳

场景:统计 /var/log 目录下所有 .log 文件中包含 “ERROR” 的行数,并将结果保存到报告文件,同时显示在屏幕。

# 逐步拆解
[whisky@centos7 ~]$ grep -r "ERROR" /var/log/*.log 2>/dev/null | wc -l | tee error-count.txt
42

[whisky@centos7 ~]$ cat error-count.txt
42

# 更进一步:生成带时间戳的报告
[whisky@centos7 ~]$ echo "=== 错误统计报告 $(date +%F %T) ===" > report.txt
[whisky@centos7 ~]$ grep -r "ERROR" /var/log/*.log 2>/dev/null | wc -l | tee -a report.txt

9.8 思考与拓展(原课后作业转化)

  1. 为什么需要 2>&1,而不是直接 2>1
    2>1 会被解析为“将错误重定向到名为 1 的文件”,而不是“重定向到文件描述符 1”。2>&1 中的 & 表示“这是一个文件描述符”。
  2. > file 2>&12>&1 > file 效果一样吗?
    不一样2>&1 必须放在 > 之后,因为它的意思是“将错误重定向到标准输出当前指向的位置”。如果放在前面,此时标准输出还指向屏幕,错误也会输出到屏幕。
  3. 什么情况下用 nohup command & 而不是 command &
    command & 将进程放入后台,但终端关闭时进程会收到 SIGHUP 信号而终止。nohup command & 让进程忽略 SIGHUP,终端关闭后继续运行。
  4. setenv 的输出有什么区别?
    set 显示所有变量(包括局部变量、环境变量和函数);env 只显示环境变量(已 export 的变量)。
  5. 单引号和双引号的根本区别是什么?
    → 双引号是“弱引用”,会展开变量($var)和命令替换($(cmd));单引号是“强引用”,所有内容原样输出,不做任何展开。

9.9 生产环境最佳实践

场景建议
脚本输出日志`./script.sh 2>&1
静默执行./script.sh >/dev/null 2>&1(丢弃所有输出)
调试管道链在关键节点插入 tee stepN.log 保存中间结果
PATH 管理~/.bashrc 中统一管理,避免重复追加
敏感信息不要用 export 暴露密码等敏感信息(用 read -s 或配置文件)
长命令可读性用反斜杠 \ 换行: `find /etc -name “*.conf”

下期预告:从数据流和变量,我们接下来进入 Linux 的用户与权限体系——这是系统安全的核心。每一期我们将学习 用户账户管理(useradd/usermod/userdel)组管理(groupadd/groupmod/groupdel)密码策略(/etc/shadow 与 chage),以及如何通过 /etc/passwd/etc/group/etc/shadow 三个核心文件理解整个账户系统。学会这些,你就能像真正的系统管理员一样“管人”了。敬请期待第七期!

— Compiled and Authored by Whisky — July 13 th, 2026
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值