适用人群:刚接触 Linux、看不懂 Shell 变量、提示符乱码、命令执行报错的零基础新手

本文配套实操实验,全程大白话 + 案例 + 避坑提醒,看完直接上手敲命令!

前言

很多刚学 Linux 的小伙伴一进 Shell 就懵:

🤔 为啥我定义变量带空格就报错?

🤔 $name_abc 取值永远不对?

🤔 改完语言重启又变回英文?

🤔 单引号双引号反斜杠到底有啥区别?

今天这篇保姆级教程,把 Shell 基础核心知识点全部拆解,搭配实操命令、踩坑预警、可视化表格,零基础也能秒懂!

一、Shell 变量入门:一行代码存数据🎯

1.1 变量是什么?

Shell 变量 = 临时储物盒,把文字、数字存在内存里,不用重复输入长串内容。

关键特性:只在当前终端会话生效,关闭窗口变量直接消失!

1.2 变量命名硬性规则🚨新手巨坑

✅ 合法:user_name、Name123、_test
❌ 非法:1name、user-name、name@test
  1. 只能由字母、数字、下划线组成
  2. 绝对不能以数字开头
  3. 不能带横杠、特殊符号、空格

1.3 变量定义、查看、取值全套实操

方式 1:简易赋值(最常用)

var1=linux
# 注意!等号左右不能加空格!
# var1 = linux 直接报错!🚨大坑1

方式 2:标准声明 declare

declare var2=shell

取出变量值:$ 变量名

echo $var1
# 输出 linux

🚨新手巨坑 2:变量名粘连识别错误

last_name=zhang
first_name=facai
echo $last_name_$first_name
# 输出 facai,系统把 last_name_ 当成完整变量,找不到为空!

解决方案:{} 大括号限定变量边界(必记)

echo ${last_name}_$first_name
# 输出 zhang_facai

1.4 变量大小写转换 declare 参数

命令效果输出结果
declare -l name=James-l 小写锁定james
declare -u name=James-u 大写锁定JAMES

1.5 查看 / 删除变量

# 查看当前终端所有变量(含系统内置变量+自定义变量)
set
# 精准过滤指定变量
set | grep first_name
# 删除变量,清空内存存储
unset first_name
echo $first_name # 无任何输出

二、环境变量:控制整个 Shell 运行规则📊

2.1 两类变量区分

  1. 自定义变量:自己临时创建,仅当前终端可用,关闭失效
  2. 环境变量:系统内置,控制语言、命令路径、提示符、编辑器等全局配置

2.2 高频环境变量对照表(收藏!)

变量名核心作用日常使用场景
PATH命令搜索路径系统去哪里找 ls、cd、vim 等命令
HOME当前用户家目录cd ~ 等价 cd $HOME
USER当前登录用户名脚本获取操作人
PWD当前所在文件夹实时显示当前路径
LANG系统语言编码解决命令乱码、中文英文切换
EDITOR默认文本编辑器visudo、crontab 默认编辑工具
PS1终端命令行提示符自定义彩色、带时间的命令行
HISTTIMEFORMAT历史命令时间戳history 查看每条命令执行时间
HISTFILE历史命令存储文件保存你敲过的所有指令

2.3 逐个实操讲解 + 踩坑提醒

1. EDITOR 修改默认编辑器

默认 visudo 用 vi,无高亮,改成 vim 体验翻倍

# 临时生效
export EDITOR=/bin/vim
visudo # 自动用vim打开sudo配置

2. LANG 切换中英文,解决中文乱码

# 英文模式
export LANG=en_US.utf8
date # 输出英文日期
# 中文模式
export LANG=zh_CN.utf8
date # 输出中文日期

⚠️ 临时设置重启终端失效,持久化教程在后文!

3. PATH 命令搜索路径【高频翻车点】

1.先通俗讲:PATH 到底是干嘛的?🎯

你把 Linux 系统想象成一座大型超市,各种命令(ls、cd、vim、chown)就是货架上的商品。

当你敲 ls 回车,系统会问:ls 这个程序在哪?我要去执行它!

PATH 就是一张货架地址清单,里面写了一堆目录路径,用冒号 : 隔开。

系统找命令的规则:

  1. 按 PATH 里从左到右的顺序,挨个去目录里翻找你输入的命令;
  2. 找到第一个匹配的程序,直接执行;
  3. 全部目录翻完都没找到 → 报错 command not found。
2.看机器原始 PATH
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

拆解开就是 5 个搜索目录:

  1. /usr/local/sbin
  2. /usr/local/bin
  3. /usr/sbin
  4. /usr/bin
  5. /root/bin

平时敲 ls,系统会从左往右找,在第 4 个目录 /usr/bin 找到 ls 程序,正常运行。

3. 结合实验分步拆解,看懂所有报错与现象🚨

🚨新手巨坑:删除 /usr/bin 下 ls 后,ls 命令直接找不到!

原理:系统只会在 PATH 写好的目录里找命令

# 查看当前命令路径
echo $PATH
# 临时追加目录到PATH(重启失效)
export PATH=$PATH:/root
# 恢复原始PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

步骤 1:把 /usr/bin 下的 ls 移到当前 root 家目录

mv /usr/bin/ls .

. 代表当前目录(现在是 /root)

原本存放 ls 的 /usr/bin 里没有 ls 了。

步骤 2:执行 ls 直接报错 command not found

ls
bash: ls: command not found...

原因:

系统拿着 PATH 清单挨个查找:/usr/local/sbin→/usr/local/bin→/usr/sbin→/usr/bin→/root/bin

所有目录里都找不到 ls,直接报错。

虽然 ls 现在在 /root,但 /root 不在 PATH 清单里,系统不会主动去 /root 翻找。

步骤 3:which ls 查不到真实程序

which ls
alias ls='ls --color=auto'
Similar command is: 'lz'

which 只会去 PATH 路径里检索可执行文件,现在 PATH 里无 ls,只能输出别名提示,找不到实体程序。

步骤 4:重置 PATH 为原始值

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

只是把 PATH 变量恢复出厂内容,此时 /usr/bin 依旧没有 ls,执行 ls 还是会报错。

步骤 5:把 /root 目录追加进 PATH 清单

export PATH=$PATH:/root
重点拆解这条命令:
  1. $PATH:读取当前旧的 PATH 全部内容;
  2. ::分隔不同目录;
  3. /root:我们要新增的搜索目录;
  4. PATH=旧内容:/root:拼接出新路径列表;
  5. export:把普通变量升级为环境变量,当前终端内所有子命令都能读取 PATH。

执行后新 PATH 变成:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root

现在系统找命令时,最后会去 /root 目录检索。

步骤 6:再次执行 ls 成功运行

ls
anaconda-ks.cfg  initial-setup-ks.cfg  ls

系统遍历 PATH 末尾的 /root,找到了我们刚移过来的 ls 程序,正常执行。

步骤 7:which ls 显示路径为 /root/ls

which ls
alias ls='ls --color=auto'
    /root/ls

证明:系统现在是从 /root 目录调取 ls 命令。

步骤 8:复原 ls 到原目录

mv ./ls /usr/bin

把 ls 放回 /usr/bin,此时 PATH 里 /usr/bin 在 /root 前面,以后执行 ls 会优先读取 /usr/bin/ls。

4. PS1 自定义终端提示符(颜值天花板)

基础提示符参数
符号含义
\u当前用户名
\h主机名简写
\W当前文件夹名
\w完整路径
\t24 小时制时分秒
$root 显示 #,普通用户显示 $
示例 1:带时间的提示符
PS1='[\u@\h \W \t]\$ '
示例 2:彩色炫酷提示符(推荐)
# 临时生效
PS1='[\[\e[91m\]\u\[\e[0m\]\[\e[93m\]@\[\e[0m\]\[\e[92;1m\]\h\[\e[0m\]\[\e[94m\] \W\[\e[0m\] \[\e[35m\]\t\[\e[0m\]]\[\e[93m\]\$\[\e[0m\] '

在这里插入图片描述

颜色码速记:

  • \[\e[31m\] 红色 \[\e[32m\] 绿色 \[\e[33m\] 黄色
  • \[\e[0m\] 重置颜色,不加会导致后续文字全变色!

5. HISTTIMEFORMAT 历史命令加时间

默认history看不到执行时间,设置后一目了然

# 完整年月日时分秒
export HISTTIMEFORMAT="%F %T "
history
# 简洁格式 月-日 时:分
export HISTTIMEFORMAT="%m-%d %H:%M "

三、变量永久保存:告别 “一关终端配置全消失”💾

🤔先搞懂痛点:为什么 export 临时设置重启就没了?

前面我们用 export 变量=xxx 改语言、改 PATH、改提示符,全是临时内存变量!

举个生活化例子:

你在备忘录临时写了一行文字,没点保存,一关备忘录(关闭终端窗口),文字直接消失。

Shell 临时变量同理:只存在当前终端的内存里,终端一关,内存清空,所有设置全部作废。

想要重启服务器、新开终端、重新 ssh 登录都保留配置,必须把配置写到 Shell 专属配置文件里,系统每次打开终端会自动读取文件加载设置,相当于 “永久保存到硬盘”。

🎯前置核心知识点:两种 Shell,读的文件不一样

Linux 打开终端分两种模式,加载配置文件的清单、顺序完全不同,搞不清就会出现「改了配置不生效」的玄学 bug!

1. Login Shell 登录式 Shell(需要输账号密码登录)

哪些场景属于 Login Shell?
  1. Xshell、FinalShell 等工具 ssh 远程连接服务器(ssh root@10.1.8.88)
  2. 机房显示器本地开机,输入用户名 + 密码登录系统
  3. su - laoma 带横杠切换用户(带 - 代表完整登录)
加载文件顺序(从上到下依次读取,后面配置会覆盖前面同名变量)
  1. /etc/profile 👉 系统全局配置,服务器所有用户共用
  2. ~/.bash_profile 👉 当前登录用户专属登录配置,仅自己生效
  3. ~/.bashrc 👉 当前用户专属 Shell 基础配置
  4. /etc/bashrc 👉 系统全局 Shell 基础配置,所有用户共用

简单流程:先读系统公共登录规则 → 再读你自己的登录专属设置 → 读取你的终端美化 / 工具配置 → 最后加载系统统一终端规则

2. NoLogin Shell 非登录式 Shell(不用重复输密码)

哪些场景属于 NoLogin Shell?
  1. 已经登录系统后,终端输入 bash 命令新开一个子终端
  2. CentOS 图形界面,鼠标点开新的终端窗口
  3. 直接运行.sh 自动化脚本(脚本默认是非登录 shell)
加载文件顺序(跳过登录专属文件)

不需要登录,直接跳过 /etc/profile、~/.bash_profile 两个登录专用文件,只加载 2 个:

  1. ~/.bashrc 👉 当前用户个人终端配置
  2. /etc/bashrc 👉 全用户通用终端配置

📊一张表分清 4 个配置文件(小白收藏)

配置文件路径生效范围哪种 Shell 会读取适合写什么配置
/etc/profile服务器全部用户仅 Login 登录 shell全局 PATH、系统默认语言 LANG
~/.bash_profile仅当前登录用户仅 Login 登录 shell个人专属登录 PATH、登录提示语
/etc/bashrc服务器全部用户Login、NoLogin 两种 shell 都读全局默认编辑器 EDITOR、全局命令别名
~/.bashrc仅当前登录用户Login、NoLogin 两种 shell 都读自定义彩色 PS1 提示符、个人工具路径、ls 别名

小科普:~ 是简写,代表当前用户的家目录

root 用户:~ = /root

laoma 普通用户:~ = /home/laoma

🛠实操:2 种永久写入方案,按需选择

方案一:全局生效|服务器所有用户都共用这套配置

适合需求:不管 root、laoma、其他普通用户,打开终端统一用同一个编辑器、统一提示符。

推荐写入文件:/etc/bashrc

原因:Login、NoLogin 两种终端都会加载这个文件,全覆盖无死角。

# 命令拆解,逐段看懂
# echo 'export EDITOR=vim' :输出一段配置文本 export EDITOR=vim
# >> 追加符号:把文字添加到文件末尾,不会删掉文件原有内容(重点!)
# /etc/bashrc 全局配置文件
echo 'export EDITOR=vim' >> /etc/bashrc

执行这条命令后:服务器任何人打开终端,$EDITOR 都会自动等于 vim,visudo、crontab 都会用 vim 编辑。

方案二:仅当前用户生效(新手首选推荐✅)

适合需求:只给自己设置,不影响服务器其他同事 / 其他账号,安全不翻车!

推荐写入文件:~/.bashrc

原因:不管 ssh 登录,还是新开 bash 子终端,都会加载,适配所有使用场景。

示例:给当前用户设置系统语言为英文

echo 'export LANG=en_US.utf8' >> ~/.bashrc

⚡关键操作:source 命令,不用重启立刻生效配置

很多小白改完配置文件,直接关掉终端重开,其实有更省事的方法!

修改配置文件后,当前终端不会自动读取新内容,有两种生效方式:

  1. 懒人方法:关闭当前终端,重新 ssh 登录 / 新开 bash 窗口
  2. 极速方法:使用 source 命令,一秒加载新配置,无需重启服务器

当前用户配置生效(修改~/.bashrc 后执行)

source ~/.bashrc

全局系统配置生效(修改 /etc/bashrc、/etc/profile 后执行)

source /etc/bashrc
source /etc/profile

🚨新手高频踩坑预警,千万别踩!

坑 1:混淆 > 和 >>,清空系统配置直接报废

> 单个大于号:覆盖写入,会清空整个文件原有内容,极度危险!

>> 两个大于号:追加写入,只在文件最后新增一行,保留原有配置,永久配置必须用 >>

错误示范(千万别敲):

echo 'export LANG=en' > /etc/profile

这条命令会直接清空 /etc/profile 全部内容,服务器登录直接出问题。

坑 2:配置写进 /etc/profile,新开 bash 子终端不生效

/etc/profile 只在 ssh 登录、本地密码登录时加载;如果你已经登录,敲 bash 新开子终端(NoLogin),不会读取这个文件,变量不会生效。

如果想要所有终端都生效,全局配置优先写 /etc/bashrc。

坑 3:改完配置不执行 source,怀疑命令写错

文件修改完成后,当前运行的终端内存里还是旧配置,必须新开终端或者 source 刷新才能看到效果。

坑 4:全局配置乱改影响他人

多人共用服务器时,尽量不要随便修改 /etc 开头的全局文件,优先用 ~/.bashrc 给自己单独配置,避免其他用户命令异常。

✨极简记忆口诀

临时变量关端就丢,永久配置写文件;

etc 开头全用户,波浪符号只自己;

登录 shell 读 profile,新开 bash 只认 rc;

改完配置输 source,不用重启秒生效!

四、命令替换 $() `` :把命令结果存进变量✨

核心作用:执行一段命令,把输出结果当成文本使用

两种写法:

  1. $(命令) 推荐,支持嵌套,可读性高
  2. 命令 反引号,老式写法,容易和单引号混淆

趣味实操案例

# 输出今天星期几
[l@centos7 ~]$ echo Today is $(date +%A)
Today is 星期五

# 创建带当天日期的文件
[l@centos7 ~]touch file-$(date +%Y%m%d)
[l@centos7 ~]ls
file-20260717 

# 计算数值
[l@centos7 ~]$ echo $[ 1+2+3 ]
6

# 获取序列
[l@centos7 ~]$ echo {1..3}
1 2 3
# 替换空格为+号
[l@centos7 ~]$ echo {1..3} | tr ' ' '+'
1+2+3

# 计算结果
[l@centos7 ~]$ echo $[ $(echo {1..100} | tr ' ' '+') ]
5050

五、引号与转义符:解决 Shell 字符乱解析难题🤯

🤔先搞懂核心痛点:为什么会解析错乱?

Shell 里有一堆自带特殊功能的符号,比如 $、*、\、(),系统看到它们不会当成普通文字,会自动执行特殊操作:

  • $变量名:读取变量内容
  • $(命令):执行命令拿到输出
  • *:匹配任意文件
  • \:用来取消符号特殊作用

但很多时候我们只想原样打印这些符号,不让系统解析,这时就要靠「转义符 \」「双引号 “”」「单引号 ‘’」三件套!

📊三大符号核心对比总表(收藏背诵)

符号核心特性内部会解析什么?最佳使用场景
反斜杠 \只转义紧跟在它后面1 个字符,单独取消单个符号特殊功能无包裹,只作用下一个字符只单独输出 1 个特殊符号:$、*、\、#
双引号 ""弱化大部分特殊符号,但保留变量、命令替换、反斜杠转义$变量、$(命令)、\ 依然生效;*、空格不会匹配文件文字里既有固定文字,又要读取变量 / 执行时间等命令
单引号 ''金钟罩模式!内部所有符号全部失去特殊能力,纯文本原样输出任何符号都不解析,$、\、() 全部当成普通文字纯固定文案,不需要调用变量、执行命令

转义符:反斜杠 \ —— 单点屏蔽工具🎯

一句话理解:\ 只管紧跟自己的那一个字符,告诉 Shell:这个符号别干活,当成普通文字打印!

实操案例 1:原样打印 $ 符号

# 不加 \,$PATH会被解析成系统路径
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

# 加 \ 锁住$,不再解析变量
echo \$PATH
$PATH

实操案例 2:打印反斜杠本身

反斜杠自己也是特殊符号,想要输出一个 \,必须用另一个 \ 转义它:

# 两个反斜杠,第一个转义第二个,最终输出1个\
echo \\
\

思考题拆解:

# 两组\\,两对转义,输出1个\
echo \\
# 三个\:前两个输出1个\,第三个单独无字符,最终还是输出1个\
echo \\\

双引号 “” —— 半屏蔽,兼顾变量与文字✨

双引号属于「半开放保护壳」:

  1. 普通符号 *、空格、括号会被锁住,不会乱匹配文件;
  2. 但是 $变量、$(命令)、\ 依旧正常工作,支持解析内容。

基础示例:同时展示变量 + 命令输出

username=xiaoming
# 双引号内 $username 会读取变量,$(date +%F)会执行日期命令
echo "欢迎$username,今天日期:$(date +%F)"
# 输出:欢迎xiaoming,今天日期:2026-07-17

进阶用法:双引号内打印纯 $ 符号

如果双引号里想原样打出 $,搭配反斜杠 \$ 即可:

echo "变量写法:\$username"
# 输出:变量写法:$username

补充小优势:双引号会保留多个连续空格

不加引号时多个空格会自动压缩成 1 个,加双引号空格完整保留:

echo hello   world   # 空格合并,输出 hello world
echo "hello   world" # 保留3个空格,输出 hello   world

单引号 ‘’ —— 全封闭金钟罩,完全不解析任何内容🛡️

单引号是最强保护壳,内部所有符号全部失效,不管是 $、\、(),通通当作普通文字原封不动输出。

实操演示

username=xiaoming
# 单引号内所有内容原样打印,不会读取变量、不会执行命令
echo '欢迎$username,今天日期:$(date +%F)'
# 输出:欢迎$username,今天日期:$(date +%F)

新手巨坑:单引号内部,反斜杠也失去转义能力🚨

echo 'Let\'s go'
# 输出 Let\s go

解释:

单引号里面 \ 不再是转义符,只是普通斜杠文字,无法用来转义单引号,所以会直接打印 \。

如果想在单引号文本里输出 ',只能跳出单引号拼接,不能用 \'。

🧠三道经典思考题完整解析

  1. echo \\

    两个反斜杠,第一个转义第二个,最终输出单个 \。

  2. echo \\\

    前两个 \\ 输出 1 个反斜杠,第三个 \ 后面没有字符,无作用,最终只输出单个 \。

  3. echo 'Let\'s go'

    单引号环境下转义符失效,\ 只是普通字符,输出 Let\s go。

📌小白快速选择口诀

  1. 只打单个特殊符号,用 \;
  2. 文字里要嵌入变量、时间、命令结果,用双引号 "";
  3. 纯固定文字,不想让系统解析任何符号,直接单引号 '';
  4. 单引号内不能用 \ 转义单引号,双引号内可以用 \$ 打印美元符。

⚠️高频踩坑提醒

  1. 忘记加引号,带空格文本直接报错;
  2. 分不清单双引号,变量打印不出来;
  3. 单引号里试图用 \' 输出单引号,结果多出斜杠;
  4. 想打印反斜杠,只写一个 \ 导致命令异常。

六、全文避坑总结清单🚨新手必看

  1. 变量赋值 var=123,等号两边绝对不能加空格,一空格直接报错
  2. 变量拼接时使用 ${变量名} 限定范围,防止识别粘连
  3. 临时环境变量重启终端失效,永久配置写入~/.bashrc并 source 生效
  4. PATH 丢失 ls 命令时,手动还原 PATH 路径即可恢复
  5. PS1 彩色提示符末尾必须加\[\e[0m\]重置颜色,否则全局文字变色
  6. 单引号内部所有符号全部原样输出,不解析变量、命令
  7. 反引号不支持嵌套,复杂命令替换优先使用 $()

结尾

Shell 变量是写自动化脚本、运维批量操作的地基,把本篇内容全部实操一遍,后续写脚本、自定义终端、配置服务器都会事半功倍!

有任何实操报错可以评论区留言,逐个解答~

更多推荐