7.Shell 基础(从零开始学)
!!!在开启一天的学习的时候,先做好快照,过程中如果出现意外的报错,解决不了的就立即恢复快照,作为初学者,省时省力,不要过于纠结哪里错了,浪费时间!!!
1.变量定义和查看
Linux 使用变量临时字符串值,便于后续引用。变量值存储在当前会话内存中。
变量名只能包含:字母、数字、下划线。变量名不能以数字开头。
shell中变量的类型,一般不需要明确指明。
# 变量定义 [fengkai@centos7 ~ 14:31:40]$ var1=key1 [fengkai@centos7 ~ 14:35:48]$ echo $var1 key1 # 标准格式如下 [fengkai@centos7 ~ 14:36:09]$ declare var1=key1 # 使用$引用变量值 [fengkai@centos7 ~ 14:36:23]$ echo $var1 key1 # 示例2 [fengkai@centos7 ~ 14:36:28]$ first_name=kai [fengkai@centos7 ~ 14:37:12]$ last_name=feng [fengkai@centos7 ~ 14:37:36]$ echo $last_name $first_name feng kai # 使用多个空格,效果一样 [fengkai@centos7 ~ 14:38:29]$ echo $last_name $first_name feng kai # 使用双引号保留多个空格 [fengkai@centos7 ~ 14:39:00]$ echo "$last_name $first_name" feng kai # 使用-和_分别对结果的影响,_导致$last_name失效,那如何使用_下划线呢? [fengkai@centos7 ~ 14:39:25]$ echo $last_name-$first_name feng-kai [fengkai@centos7 ~ 14:41:01]$ echo $last_name_$first_name kai # 使用{}限定变量范围,这样_就不影响了 [fengkai@centos7 ~ 14:43:44]$ echo ${last_name}_$first_name feng_kai # 当前shell中所有变量 [fengkai@centos7 ~ 14:44:40]$ set ····· 有很多 ····· # set命令还会显示函数 [fengkai@centos7 ~ 14:44:40]$ set | grep first_name first_name=kai # 取消变量定义 [fengkai@centos7 ~ 14:45:51]$ echo $first_name kai [fengkai@centos7 ~ 14:46:33]$ unset first_name [fengkai@centos7 ~ 14:48:00]$ echo $first_name # 定义变量时候,转换变量大小写 [fengkai@centos7 ~ 14:48:02]$ declare -l name=Feng [fengkai@centos7 ~ 14:48:46]$ echo $name feng [fengkai@centos7 ~ 14:48:50]$ declare -u name=Feng [fengkai@centos7 ~ 14:48:58]$ echo $name FENG2.环境变量
根据变量是否是用户定义:
- shell 环境内置变量:设置shell的运行环境。
- 用户自定义变量:字面意思,用户自己定义的变量,也就是普通变量。
部分shell环境变量如下:
| 环境变量名 | 作用 |
|---|---|
| EDITOR | 默认编辑器 |
| HISTFILE | 历史文件位置 |
| HISTFILESIZE | 历史命令个数 |
| HISTTIMEFORMAT | 历史命令时间格式 |
| PS1 | 命令行提示符 |
| LANG | shell 环境语言 |
| PATH | 命令搜素路径 |
| HOME | 当前用户家目录 |
| USER | 当前用户 |
| PWD | 当前shell路径 |
完整的shell 环境变量参考bash(1)。
2.1 EDITOR(注意权限)
[root@centos7 /etc 14:52:38]# visudo # 以上命令默认使用vi 编辑文件/etc/sudoers,不显示语法高亮[root@centos7 /etc 14:55:33]# export EDITOR=/bin/vim # 或者 [root@centos7 /etc 14:56:03]# EDITOR=/bin/vim vim vimdiff vimtutor [root@centos7 /etc 14:56:03]# EDITOR=/bin/vim visudo # 以上命令使用vim 编辑文件/etc/sudoers,显示语法高亮2.2 LANG(注意权限)
# 由中文切换为英文显示时间 [root@centos7 /etc 14:56:58]# date 2026年 07月 17日 星期五 14:57:52 CST [root@centos7 /etc 14:57:52]# export LANG=en_US.utf8 [root@centos7 /etc 14:58:17]# date Fri Jul 17 14:58:20 CST 2026 # 由英文切换为中文显示时间 [root@centos7 /etc 14:58:20]# export LANG=zh_CN.utf8 [root@centos7 /etc 14:59:30]# date 2026年 07月 17日 星期五 14:59:31 CST常见 LANG代码:
- 英语:en_US.utf8
- 简体中文:zh_CN.utf8
- 繁体中文:zh_TW.utf8
2.3 PATH(注意权限)
# 查看系统命令的路径 [root@centos7 /etc 15:03:28]# echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/fengkai/.local/bin:/home/fengkai/bin # 将ls的系统命令转移到当前文件下面,要注意当前文件是/etc,cd到初始目录下 [root@centos7 /etc 15:09:01]# cd [root@centos7 ~ 15:03:37]# mv /usr/bin/ls . [root@centos7 ~ 15:05:14]# ls bash: ls: 未找到命令... 相似命令是: 'lz' # 我们刚刚把ls移动到了/root的根目录下,通过/root/ls可以执行ls命令查看 [root@centos7 ~ 15:09:05]# /root/ls anaconda-ks.cfg ls 公共 视频 文档 音乐 initial-setup-ks.cfg test.txt 模板 图片 下载 桌面 # 看不到ls的位置 [root@centos7 ~ 15:12:52]# which ls alias ls='ls --color=auto' # 将/root目录追加到PATH中并查看当前的PATH,对比之前的,多了/root,这样ls就可以执行了,which也找到了对应的位置 [root@centos7 ~ 15:13:12]# export PATH=$PATH:/root [root@centos7 ~ 15:14:25]# ls anaconda-ks.cfg ls 公共 视频 文档 音乐 initial-setup-ks.cfg test.txt 模板 图片 下载 桌面 [root@centos7 ~ 15:14:28]# echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/fengkai/.local/bin:/home/fengkai/bin:/root [root@centos7 ~ 15:14:44]# which ls alias ls='ls --color=auto' /root/ls # 将ls移动到原来 [root@centos7 ~ 15:17:41]# mv ./ls /usr/bin [root@centos7 ~ 15:17:45]# which ls alias ls='ls --color=auto' /usr/bin/ls2.4 PS1(注意权限)
[fengkai@centos7 ~]$ echo $PS1 [\u@\h \W]\$ [fengkai@centos7 ~]$ man bash man bash 搜索PROMPTING # 扩展说明: \h 主机名,第一个 `.' 之前的部分 \H 主机名 \n 新行符 \t 当前时间,采用 24小时制的 HH:MM:SS 格式 \T 当前时间,采用 12小时制的 HH:MM:SS 格式 \@ 当前时间,采用 12小时制上午/下午 (am/pm) 格式 \A 当前时间,采用 24小时制上午/下午格式 \u 当前用户的用户名 the username of the current user \w 当前工作目录 \W 当前工作目录的基本部分 \$ 如果有效 UID 是 0,就是 #, 其他情况下是 $ # 提示符由[fengkai@centos7 ~]$变为了hello [fengkai@centos7 ~]$ PS1='hello' hello # 敲如下命令,提示符又恢复回来了 PS1='[\u@\h \W \t]\$ ' [fengkai@centos7 ~ 16:06:35]$ # 显示完整工作目录 [fengkai@centos7 ~ 16:08:16]$ PS1='[\u@\h \w \t]\$ ' [fengkai@centos7 ~ 16:08:20]$ cd /usr/share/doc [fengkai@centos7 /usr/share/doc 16:08:29]$彩色提示符
# 代码: # \[\e[0;30m\]:黑色 # \[\e[0;31m\]:红色 # \[\e[0;32m\]:绿色 # \[\e[0;33m\]:黄色 # \[\e[0;34m\]:蓝色 # \[\e[0;35m\]:紫色 # \[\e[0;36m\]:青色 # \[\e[0;37m\]:白色 # \[\e[0m\]:恢复默认颜色示例:
# root权限下vim /etc/bashrc 文件末尾添加一行 [root@centos7 fengkai]# vim /etc/bashrc 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\] ' # 或者 echo 追加 echo "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\] '" >> /etc/bashrc # 注意 echo追加的PS1与直接vim的是不一致的,体现在\\\$。推出登陆,并重新连接之后,提示符就有颜色显示了
2.5 HISTTIMEFORMAT
控制历史命令时间格式。通过设置该变量,可以在执行history命令时显示每条历史命令的执行时间。
常用配置示例(上图最后的一行就是HISTTIMEFORMAT="%F %T ")
- 显示年月日时分秒(如
2024-10-24 15:30:45):
bash export HISTTIMEFORMAT="%F %T "
效果:history输出会类似1000 2024-10-24 15:30:45 ls -l
- 显示更简洁的时间格式(如
10-24 15:30):
bash export HISTTIMEFORMAT="%m-%d %H:%M "
HISTTIMEFORMAT支持的常见时间格式符:
%F:完整日期(年 - 月 - 日,如2024-10-24)%T:完整时间(时:分: 秒,如15:30:45)%Y:四位年份(如2024)%m:两位月份(01-12)%d:两位日期(01-31)%H:24 小时制小时(00-23)%M:分钟(00-59)%S:秒(00-59)
3.变量持久化保存
- login shell 启动的时候,会按顺序加载以下配置文件中配置: 1. /etc/profie,限定所有用户,设置操作系统级别。 2. \~/.bash_profile,只限定特定用户 3. ~/.bashrc,只限定特定用户 4. /etc/bashrc,限定所有用户
- nologin shell启动的时候,会按顺序加载以下配置文件中配置: 1. ~/.bashrc,只限定特定用户,例如限定laoma用户 /home/laoma/.bashrc。 2. /etc/bashrc,限定所有用户
# login shell 示例 [root@centos7 fengkai 16:34:14]# echo 'export LANG=en_US.utf8' >> /etc/profile # 验证 Connecting to 10.1.8.10:22... Connection established. To escape to local shell, press 'Ctrl+Alt+]'. Last login: Fri Jul 17 16:32:35 2026 from 10.1.8.1 # nologin shell 示例 [root@centos7 fengkai 16:46:35]# echo 'export EDITOR=vim' >> /etc/bashrc # 验证 [fengkai@centos7 ~ 16:50:49]$ bash [fengkai@centos7 ~ 16:53:19]$ echo $EDITOR vim4.命令替换
格式如下:
- $(COMMAND)
- `COMMAND`
效果如下:
# 查看星期几 [fengkai@centos7 ~ 16:59:12]$ echo Today is `date +%A` Today is 星期五 # 查看现在的时间 [fengkai@centos7 ~ 16:59:15]$ echo The time is $(date +%M) minutes past $(date +%l%p). The time is 59 minutes past 4下午 #新建一个带日期的文件 [fengkai@centos7 ~ 17:00:01]$ touch file-$(date +%Y%m%d) # 或者 [fengkai@centos7 ~ 17:00:17]$ touch file-`date +%Y%m%d` [fengkai@centos7 ~ 17:00:27]$ ls allinone file- file-3 passwd.list profile.sh 视频 音乐 bashrc file-1 file.tar passwd.man testfile 图片 桌面 dhcpd.conf file-2 passwd2.list passwd.stdout 公共 文档 ext4.man file-20260717 passwd.all profile 模板 下载如何计算 1+2+..+99+100的值?
# 计算数值 [fengkai@centos7 ~ 17:00:28]$ echo $[1+2+3] 6 # 获取序列 [fengkai@centos7 ~ 17:03:59]$ echo {1..3} 1 2 3 # 替换空格为+号 [fengkai@centos7 ~ 17:04:17]$ echo {1..3} | tr ' ' '+' 1+2+3 # 计算结果,直接带入会出现错误,需要用$()将上面的命令填入 [fengkai@centos7 ~ 17:04:35]$ echo $[echo {1..3} | tr ' ' '+'] -bash: echo 1 | tr ' ' '+': 表达式中有语法错误 (错误符号是 "1 | tr ' ' '+'") [fengkai@centos7 ~ 17:05:32]$ echo $[$(echo {1..3} | tr ' ' '+')] 6 [fengkai@centos7 ~ 17:05:48]$ echo $[$(echo {1..100} | tr ' ' '+')] 50505.保留字符字面含义
许多字符在bash中有特殊的意义,忽略这些含义,使用引号和转义字符。
- \,取消后面单个字符的特殊含义。
- 双引号(""),压缩shell扩展含义,不压缩命令替换、变量替换和转义字符(\)。
- 单引号(''),可以压缩单引号内部的所有字符含义。
# \ 示例,将$PATH直接输出 [fengkai@centos7 ~ 17:05:57]$ echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/fengkai/.local/bin:/home/fengkai/bin [fengkai@centos7 ~ 17:08:12]$ echo \$PATH $PATH # "" 示例,不加"",*会将所有文件显示两次,加上就会正常 [fengkai@centos7 ~ 17:11:05]$ username=fengkai [fengkai@centos7 ~ 17:12:30]$ echo * welcome $username to my home on $(date +%F) * bashrc dhcpd.conf 公共 模板 视频 图片 文档 下载 音乐 桌面 welcome fengkai to my home on 2026-07-17 bashrc dhcpd.conf 公共 模板 视频 图片 文档 下载 音乐 桌面 [fengkai@centos7 ~ 17:12:34]$ echo "* welcome $username to my home on $(date +%F) *" * welcome fengkai to my home on 2026-07-17 * # \和"" 示例,将$username直接输出 [fengkai@centos7 ~ 17:13:19]$ echo "* welcome \$username to my home on $(date +%F) *" * welcome $username to my home on 2026-07-17 * # '' 示例,不论加不加\,$username直接输出,加了\,连同\一起输出 [fengkai@centos7 ~ 17:13:52]$ echo '* welcome $username to my home on $(date +%F) *' * welcome $username to my home on $(date +%F) * [fengkai@centos7 ~ 17:14:24]$ echo '* welcome \$username to my home on $(date +%F) *' * welcome \$username to my home on $(date +%F) *思考:
# 下面命令的输出 [fengkai@centos7 ~ 17:17:54]$ echo \ > [fengkai@centos7 ~ 17:17:45]$ echo \\ \ # 最终输出一个 \ 符号 [laoma@centos7 ~]$ echo \\\ # 最终输出一个 \ 符号 [fengkai@centos7 ~ 17:18:27]$ echo \\\\ \\ ## 最终输出一个 \\ 符号 # 下面命令的输出,Let\为一段,s go为一段,加起来如下显示 [fengkai@centos7 ~ 17:19:28]$ echo 'Let\'s go' > ' Let\s go # 使用 echo 一次性在文件中输入多行字符串 [fengkai@centos7 ~ 17:20:41]$ echo "hello1 > hello2 > hello3">hello.txt [fengkai@centos7 ~ 17:22:46]$ cat hello.txt hello1 hello2 hello36.综合练习
1.变量名规范。
Linux 使用变量临时字符串值,便于后续引用。变量值存储在当前会话内存中。
变量名只能包含:字母、数字、下划线。变量名不能以数字开头。
2.变量如何定义和查看,举例说明。
定义变量xxx
xxx=fengkai
查看变量xxx
echo $xxx
3.如何扩展变量范围,举例说明。
echo $xxx $yyy
4.解释以下环境变量作用,举例说明。 - EDITOR - PS1 - LANG - PATH
EDITOR:设置编辑器,通过visudo命令,设置显示是否高亮
PS1:命令提示符设置,通过PS1=[\u\w\t....参数],还可以设置颜色
LANG:系统语言选择,主要为英文和中文
PATH:主要是系统命令的相关路径
5.命令替换作用,举例说明。
主要为$(xxx)和`xxx`两种
echoe $(date +%A)或者`date +%A`
6.解释以下符号作用,举例说明。 - 转义符号(\) - 双引号("") - 单引号('')
\符号:取消后面单个字符的特殊含义
举例:echo $PATH显示系统命令的路径,echo \$PATh显示为$PATH
""符号:压缩shell扩展含义,不压缩命令替换、变量替换和转义字符(\)
举例:echo "* \$PATH",显示为* $PATH,*被压缩显示,\没有
''符号:可以压缩单引号内部的所有字符含义
举例:echo '* \$PATH',显示为* \$PATH,*和\都被压缩显示出来了
