1.Shell 基础

变量定义和查看

变量规则

  1. 命名字符:仅字母、数字、下划线
  2. 限制:不能以数字开头,区分大小写
  3. 无需声明数据类型,默认全为字符串;数值运算需专用语法
  4. 生命周期:仅当前 Shell 会话有效,退出终端丢失
# 变量定义
[xzh@centos7 ~ 10:20:16]$ var1=key1

# 标准格式如下
[xzh@centos7 ~ 10:25:35]$ declare var1=key1

# 使用$引用变量值
[xzh@centos7 ~ 10:25:59]$ echo $var1 
key1

# 示例2
[xzh@centos7 ~ 10:27:00]$ first_name=zhiheng
[xzh@centos7 ~ 10:27:05]$ last_name=xu
[xzh@centos7 ~ 10:27:10]$ echo $last_name $first_name 
xu zhiheng

# 使用多个空格,效果一样
[laoma@centos7 ~]$ echo $last_name   $first_name
zhang facai
# 使用引号保留多个空格
[xzh@centos7 ~ 10:27:24]$ echo "$last_name $first_name" 
xu zhiheng

[xzh@centos7 ~ 10:27:52]$ echo $last_name-$first_name 
xu-zhiheng
[xzh@centos7 ~ 10:28:05]$ echo $last_name_$first_name 
zhiheng

# 使用{}限定变量范围
[xzh@centos7 ~ 10:28:38]$ echo ${last_name}_$first_name 
xu_zhiheng

# 当前shell中所有变量
[xzh@centos7 ~ 10:28:51]$ set

# set命令还会显示函数
[xzh@centos7 ~ 10:28:58]$ set | grep first_name
first_name=zhiheng

# 取消变量定义
[xzh@centos7 ~ 10:29:42]$ unset first_name 
[xzh@centos7 ~ 10:30:05]$ echo $first_name

# 定义变量时候,转换变量大小写
[xzh@centos7 ~ 10:30:39]$ declare -l name=James
[xzh@centos7 ~ 10:30:43]$ echo $name
james
[xzh@centos7 ~ 10:30:51]$ declare -u name=James
[xzh@centos7 ~ 10:30:55]$ echo $name
JAMES

环境变量

根据变量是否是用户定义:

  • 自定义本地变量

仅当前 Shell 会话可用,子 Shell 无法读取,未 export 导出,退出终端失效。

定义:var=test

查看:set

  • 环境变量(全局变量)

通过export导出,当前会话、子进程 / 子 Shell 均可读取;系统自带内置环境变量永久存在。

查看:env / printenv

部分shell环境变量如下:

变量名 功能说明 示例查看命令
HOME 当前登录用户家目录 echo $HOME
USER 当前登录用户名 echo $USER
PWD 当前所在工作目录 echo $PWD
PATH 系统命令检索路径,执行命令时依次查找 echo $PATH
LANG 系统语言编码(中文 zh_CN.UTF-8) echo $LANG
PS1 终端提示符样式(root@主机 时间 #) echo $PS1
HISTFILE 历史命令存储文件,默认~/.bash_history echo $HISTFILE
HISTFILESIZE 历史文件最大存储行数 echo $HISTFILESIZE
HISTTIMEFORMAT history 命令输出的时间格式化字符串 export HISTTIMEFORMAT="%F %T "
EDITOR 系统默认文本编辑器 echo $EDITOR

完整的shell 环境变量参考bash(1)。

EDITOR

[root@centos7 ~ 10:48:19]# visudo
# 以上命令默认使用vi 编辑文件/etc/sudoers,不显示语法高亮

[root@centos7 ~ 11:12:09]# export EDITOR=/bin/vim
[root@centos7 ~ 11:12:33]# visudo

LANG

[root@centos7 ~ 11:12:45]# date
2026年 07月 17日 星期五 11:12:57 CST
[root@centos7 ~ 11:12:57]# export LANG=en_US.utf8
[root@centos7 ~ 11:13:23]# date
Fri Jul 17 11:13:25 CST 2026

[root@centos7 ~ 11:13:25]# export LANG=zh_CN.utf8
[root@centos7 ~ 11:13:36]# date
2026年 07月 17日 星期五 11:13:37 CST

常见 LANG代码:

  • 英语:en_US.utf8
  • 简体中文:zh_CN.utf8

PATH

[root@centos7 ~ 11:13:57]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@centos7 ~ 11:14:21]# mv /usr/bin/ls .
[root@centos7 ~ 11:14:32]# ls
bash: ls: 未找到命令...
相似命令是: 'lz'
[root@centos7 ~ 11:14:33]# which ls
alias ls='ls --color=auto'

# 设置为原来的值
[root@centos7 ~ 11:15:45]# PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@centos7 ~ 11:17:04]# export PATH=$PATH:/root
[root@centos7 ~ 11:17:27]# ls
anaconda-ks.cfg  dhcpd.conf  initial-setup-ks.cfg  ls
[root@centos7 ~ 11:17:28]# which ls
alias ls='ls --color=auto'
	/root/ls

# ls移动到原来为止
[root@centos7 ~ 11:17:36]# mv ./ls /usr/bin

PS1

[root@centos7 ~ 11:17:55]# echo $PS1
[\[\e[91m\]\u\[\e[93m\]@\[\e[92;1m\]\h\[\e[0m\] \[\e[94m\]\W\[\e[0m\] \[\e[35m\]\t\[\e[0m\]]\[\e[93m\]\$\[\e[0m\]

[root@centos7 ~ 11:18:17]# 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,就是 #, 其他情况下是 $

# 提示符变为了'HELLO '
[xzh@centos7 ~ 11:20:36]$ PS1='HELLO'
HELLO echo hello world
hello world
HELLO
ctrl+d

# 提示符带时间
[xzh@centos7 ~ 11:22:50]$PS1='[\u@\h \W \t]\$'
[xzh@centos7 ~ 11:23:18]$

# 显示完整工作目录
[xzh@centos7 ~ 11:23:23]$PS1='[\u@\h \w \t]\$ '
[xzh@centos7 ~ 11:23:38]$ cd /usr/share/doc
[xzh@centos7 /usr/share/doc 11:23:48]$ 

#将PS1改回初始状态
[xzh@centos7 doc 11:24:54]$ PS1='[\[\e[91m\]\u\[\e[93m\]@\[\e[92;1m\]\h\[\e[0m\] \[\e[94m\]\W\[\e[0m\] \[\e[35m\]\t\[\e[0m\]]\[\e[93m\]\$\[\e[0m\]'

彩色提示符

# 代码:
# \[\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\]:恢复默认颜色

示例:

# 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的是不一致的,体现在\\\$。

HISTTIMEFORMAT

控制历史命令时间格式。通过设置该变量,可以在执行 history 命令时显示每条历史命令的执行时间。

常用配置示例

  1. 显示年月日时分秒(如 2024-10-24 15:30:45):
bash export HISTTIMEFORMAT="%F %T "

#调用命令后执行history,查看历史命令的执行时间
[root@centos7 ~ 11:32:53]# export HISTTIMEFORMAT="%F %T "
[root@centos7 ~ 11:33:05]# history 
    1  2026-07-17 11:33:05 export HISTTIMEFORMAT="%F %T "
    2  2026-07-17 11:33:08 history 

效果:history 输出会类似 1000 2024-10-24 15:30:45 ls -l

  1. 显示更简洁的时间格式(如 10-24 15:30):
bash export HISTTIMEFORMAT="%m-%d %H:%M "

#调用命令后执行history,查看历史命令的执行时间
[root@centos7 ~ 11:33:12]# export HISTTIMEFORMAT="%m-%d %H:%M "
[root@centos7 ~ 11:33:27]# history 
    1  07-17 11:33 export HISTTIMEFORMAT="%F %T "
    2  07-17 11:33 history 
    3  07-17 11:33 export HISTTIMEFORMAT="%m-%d %H:%M "
    4  07-17 11:33 history 

HISTTIMEFORMAT 支持的常见时间格式符:

格式符 含义 示例
%F 完整日期 (年 - 月 - 日) 2026-07-17
%T 完整时间 (时:分: 秒) 17:02:29
%Y 四位年份 2026
%m 两位月份 (01~12) 07
%d 两位日期 (01~31) 17
%H 24 小时制小时 (00~23) 17
%M 两位分钟 (00~59) 02
%S 两位秒数 (00~59) 29

变量持久化保存

一、登录 Shell(login shell)加载顺序

  1. /etc/profile:全局系统级,所有登录用户生效
  2. ~/.bash_profile:当前用户私有配置
  3. ~/.bashrc:当前用户 Shell 环境配置
  4. /etc/bashrc:全局 Shell 基础配置

二、非登录 Shell(nologin shell,如直接新开终端窗口、ssh 非登录执行命令)加载顺序

  1. ~/.bashrc:当前用户私有配置
  2. /etc/bashrc:全局通用配置

补充关键点

  1. 持久化环境变量 / 别名:
    • 全局所有用户永久生效:写入/etc/profile/etc/bashrc
    • 仅当前用户永久生效:写入~/.bash_profile~/.bashrc
[root@centos7 ~ 13:53:03]# echo 'export LANG=en_US.utf7' >>/etc/profile
[root@centos7 ~ 13:53:17]# 

Connection closed.

Disconnected from remote host(10.1.8.10) at 13:53:24.

Type `help' to learn how to use Xshell prompt.
[C:\~]$ 

Connecting to 10.1.8.10:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

Last login: Fri Jul 17 11:21:20 2026 from 10.1.8.1

[xzh@centos7 ~ 13:53:34]$ date 
Fri Jul 17 13:54:00 CST 2026

# nologin shell 示例
[root@centos7 ~ 14:38:48]# echo 'export EDITOR=vim' >> /etc/bashrc

# 验证
[root@centos7 ~ 14:38:52]# bash
[root@centos7 ~ 14:38:55]# echo $EDITOR
vim

命令替换

格式如下:

  • $(COMMAND)或COMMAND

效果如下:

[xzh@centos7 ~ 14:13:14]$ echo Today is `date +%A`
Today is 星期五
[xzh@centos7 ~ 14:13:47]$ echo The time is $(date +%M) minutes past $(date +%l%p).
The time is 36 minutes past 2下午.

[xzh@centos7 ~ 14:36:07]$ touch file-$(date +%Y%m%d)
#或者
[xzh@centos7 ~ 14:36:26]$ touch file-`date +%Y%m%d`
[xzh@centos7 ~ 14:36:31]$ ls
dhcpd.conf     pass.err    passwd.list  test      公共  图片  音乐
ext4.man       passwd.all  passwd.man   test.txt  模板  文档  桌面
file-20260717  passwd.err  profile.sh   xzh.txt   视频  下载

# 计算数值
[root@centos7 ~ 14:10:46]# echo $[ 1+2+3 ]
6

# 获取序列
[root@centos7 ~ 14:11:07]# echo {1..3}
1 2 3

# 替换空格为+号
[root@centos7 ~ 14:11:55]# echo {1..3} | tr ' ' '+'
1+2+3

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

保留字符字面含义

转义符 \:仅消除紧跟单个字符的特殊功能。

例:echo \$PATH 原样输出 $PATH

双引号 " ":屏蔽通配符、空格拆分;** 保留变量、命令替换()/``、转义 ** 三种解析。

单引号 ' ':内部所有符号全部失去特殊含义,原样输出,无任何解析。

简易区分

  • 要解析变量 / 命令:用双引号
  • 纯文本、原样输出:用单引号
  • 仅单个符号取消特殊含义:用反斜杠 \
# \ 示例
[root@centos7 ~ 14:43:54]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@centos7 ~ 14:44:10]# echo \$PATH
$PATH


# "" 示例
[root@centos7 ~ 14:44:35]# username=xuzhiheng
[root@centos7 ~ 14:51:02]# echo ******* Welcome $username to Linux Classroom On $(date +%F) *******
anaconda-ks.cfg dhcpd.conf initial-setup-ks.cfg Welcome xuzhiheng to Linux Classroom On 2026-07-17 anaconda-ks.cfg dhcpd.conf initial-setup-ks.cfg

[root@centos7 ~ 14:51:12]# echo "******* Welcome $username to Linux Classroom On $(date +%F) *******"
******* Welcome xuzhiheng to Linux Classroom On 2026-07-17 *******

# \和"" 示例
[root@centos7 ~ 14:51:32]# echo "******* Welcome \$username to Linux Classroom On $(date +%F) *******"
******* Welcome $username to Linux Classroom On 2026-07-17 *******

# '' 示例
[root@centos7 ~ 14:51:50]# echo '******* Welcome $username to Linux Classroom On $(date +%F) *******'
******* Welcome $username to Linux Classroom On $(date +%F) *******

思考:

# 下面命令的输出
[xzh@centos7 ~ 16:47:12]$ echo \\
\
# 最终输出一个 \ 符号

[xzh@centos7 ~ 16:47:22]$ echo \\\
> 
\
# 最终输出一个 \ 符号

# 下面命令的输出
[xzh@centos7 ~ 16:47:39]$ echo 'Let\'s go'
> '
> echo 'Let\'s go'


# 使用 echo 一次性在文件中输入多行字符串
[xzh@centos7 ~ 16:49:11]$ echo "hello 1
> hello 2
> hello 3
> hello 4"
hello 1
hello 2
hello 3
hello 4

2.Linux 用户和组管理

用户和组介绍

用户介绍

用户账号是 Linux 系统安全的核心基础。系统中所有运行进程都归属某一用户,每一个文件、目录也都绑定专属属主,依靠文件归属实现权限管控;进程对应的用户身份,直接决定该进程能读写哪些文件、访问哪些资源。

对外我们通过用户名区分账号方便操作,系统底层依靠唯一 UID(用户 ID)识别用户。登录账号一般会配置密码,用于身份校验。

用户帐户主要有三种类型:

  • 超级用户(root):系统最高管理账号,用户名固定 root,UID=0,拥有系统全部操作权限,无任何访问限制。

  • 系统用户:专供后台服务、守护进程运行使用的非特权账号,不具备完整操作权限,用于隔离服务资源、保障系统安全;不支持交互式登录,仅后台程序调用。

  • 普通用户:日常办公、操作使用的标准账号,权限受限,仅能操作自身家目录与授权资源,是绝大多数使用者的登录账号。

passwd 文件

/etc/passwd 文件保存操作系统登录用户信息。每行包含一个登录用户信息,以冒号分隔七个域。

格式:

name:password:UID:GID:GECOS:directory:shell

示例:

xzh:x:1000:1000:software admin:/home/laoma:/bin/bash

解释如下:

  • name:用户登录名
  • password:用户密码,以x表示
  • UID:用户ID
  • GID:用户主组ID
  • GECOS:用户描述信息,通常为用户的真实姓名
  • directory:用户主目录,启动shell时的工作目录,默认位于/home/username
  • shell:用户打开终端时运行的程序,默认是shell。

对于system user,它的shell是/sbin/nologin。

示例:

[xzh@centos7 ~ 16:20:25]$ grep postfix /etc/passwd
postfix:x:89:89::/var/spool/postfix:/sbin/nologin

group 文件

**组是用户的集合,组中用户继承组权限。**与用户一样,组具有组名称以使其更易于使用。系统通过分配给它们的唯一标识号,组ID或GID来区分组。

/etc/group 文件保存操作系统组信息。每行包含一个组信息,以冒号分隔4个域。格式:

group_name:password:GID:user_list

示例:

[xzh@centos7 ~ 16:50:18]$ grep wheel /etc/group
wheel:x:10:xzh

解释如下:

  • group_name:组名称
  • password:组密码,用x表示
  • GID:组ID,唯一表示组
  • user_list:作为补充的成员

组的类型

  • 主要组:每个用户只有一个主要组,/etc/passwd 文件中的GID编号定义。 默认情况下,**用户创建的新文件组所有者为用户的主要组。**通常,在创建新的常规用户时,会创建一个与该用户同名的新组。该组用作新用户的主要组,该用户是此用户专用组的唯一成员,有助于简化文件权限管理。
  • 补充组:用户还可以拥有补充组。 补充组的成员资格由/etc/group文件确定。 根据用户的任何组是否具有访问权限,授予用户访问权限的权限。例如,如果用户user01具有主要组user01和补充组wheel和webadmin,则该用户可以读取这三个组中任何一个组可读的文件。
# 查看用户信息
[xzh@centos7 ~ 16:49:47]$ id
uid=1000(xzh) gid=1000(xzh) groups=1000(xzh),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

# 查看用户 uid
[xzh@centos7 ~ 16:50:59]$ id -u xzh
1000

本地用户管理

whoami 命令

查看当前终端中登录的用户。

[xzh@centos7 ~ 16:51:12]$ whoami
xzh

who 和 w 命令

查看当前系统中所有终端上登录的用户,以及用户登录的时间。

[xzh@centos7 ~ 16:51:26]$ who
xzh      :0           Jul 17 08:53 (:0)
xzh      pts/0        Jul 17 16:02 (10.1.8.1)
xzh      pts/1        Jul 17 09:09 (10.1.8.1)

[xzh@centos7 ~ 16:51:42]$ w
 16:51:44 up  7:58,  3 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
xzh      :0       :0               08:53   ?xdm?   3:31   0.76s /usr/libexec/gnome-session-binary --sessi
xzh      pts/0    10.1.8.1         16:02    0.00s  0.24s  0.06s w
xzh      pts/1    10.1.8.1         09:09   30:56   0.16s  0.16s -bash

users 命令

查看当前系统中所有终端上登录的用户名。

[root@centos7 ~ 16:53:43]# users
xzh xzh xzh

useradd 命令

作用:创建用户

# 用户1
[root@centos7 ~ 16:54:03]# useradd user01
[root@centos7 ~ 16:54:39]# grep user01 /etc/passwd
user01:x:1001:1001::/home/user01:/bin/bash

# 用户2
[root@centos7 ~ 16:58:09]# useradd -u 8888 -d /opt/user02 -c "user for software manage" -g wheel -s /sbin/nologin user02
# -u uid
# -d 用户的家目录
# -c 描述信息
# -g 用户的主组
# -s 用户shell程序

[root@centos7 ~ 16:58:14]# grep user02 /etc/passwd
user02:x:8888:10:user for software manage:/opt/user02:/sbin/nologin
[root@centos7 ~ 16:58:26]# ls -d /opt/user02/
/opt/user02/

# 创建一个没有密码的账户,该用户在图形化界面中可以直接登录
[root@centos7 ~ 16:58:40]# useradd -p '' tom

新用户家目录中的文件来源于 /etc/skel/ 目录。

[root@centos7 ~ 16:58:51]# ls -a ~tom
.  ..  .bash_logout  .bash_profile  .bashrc  .mozilla
[root@centos7 ~ 16:59:11]# ls -a /etc/skel/
.  ..  .bash_logout  .bash_profile  .bashrc  .mozilla
[root@centos7 ~ 16:59:19]# 

创建用户的时候,用户属性默认参数配置在 /etc/login.defs 文件。

[root@centos7 ~ 16:59:25]# vim /etc/login.defs 
MAIL_DIR        /var/spool/mail
UMASK           022
HOME_MODE       0700

PASS_MAX_DAYS   99999
PASS_MIN_DAYS   0
PASS_MIN_LEN    5
PASS_WARN_AGE   7

# Min/max values for automatic uid selection in useradd
UID_MIN                  1000
UID_MAX                 60000
# System accounts
SYS_UID_MIN               201
SYS_UID_MAX               999

# Min/max values for automatic gid selection in groupadd
GID_MIN                  1000
GID_MAX                 60000
# System accounts
SYS_GID_MIN               201
SYS_GID_MAX               999

CREATE_HOME     yes
USERGROUPS_ENAB yes
...

usermod 命令

作用:修改用户属性。

[root@centos7 ~ 17:00:38]# usermod user02 -u 1008 -md /home/user02 -s /bin/bash
# -m 移动家目录到新的位置

[root@centos7 ~ 17:00:52]# grep user02 /etc/passwd
user02:x:1008:10:user for software manage:/home/user02:/bin/bash
[root@centos7 ~ 17:01:02]# ls -d /home/user02/
/home/user02/

[root@centos7 ~ 17:01:12]# su - user02
[user02@centos7 ~ 17:01:24]$ 

# 添加补充组,如果没有-a选项,则代表将补充组设置为user01,原先的补充组就被覆盖了。
[root@centos7 ~ 17:03:20]# usermod -aG user01 user02
[root@centos7 ~ 17:03:51]# id user02
uid=1008(user02) gid=10(wheel) groups=10(wheel),1001(user01)

userdel 命令

# 正常删除
[root@centos7 ~ 17:04:01]# useradd user03
[root@centos7 ~ 17:04:16]# userdel user03

# 强制删除
[root@centos7 ~ 17:04:21]# userdel user02
userdel: user user02 is currently used by process 10509
[root@centos7 ~ 17:04:25]# id user02
uid=1008(user02) gid=10(wheel) groups=10(wheel),1001(user01)

# 尽量不要强制删除,要找到无法删除的原因
#只用 userdel user02 只会删用户,保留 /home/user02 目录;-r 一并删除家目录与邮件文件。
[root@centos7 ~ 17:04:47]# userdel -f user02
userdel: user user02 is currently used by process 10509
[root@centos7 ~ 17:05:04]# is user02
bash: is: command not found...
# id user02
uid=1008(user02) gid=10(wheel) groups=10(wheel),1001(user01)

userdel 命令

# 正常删除
[root@centos7 ~ 17:04:01]# useradd user03
[root@centos7 ~ 17:04:16]# userdel user03

# 强制删除
[root@centos7 ~ 17:04:21]# userdel user02
userdel: user user02 is currently used by process 10509
[root@centos7 ~ 17:04:25]# id user02
uid=1008(user02) gid=10(wheel) groups=10(wheel),1001(user01)

# 尽量不要强制删除,要找到无法删除的原因
#只用 userdel user02 只会删用户,保留 /home/user02 目录;-r 一并删除家目录与邮件文件。
[root@centos7 ~ 17:04:47]# userdel -f user02
userdel: user user02 is currently used by process 10509
[root@centos7 ~ 17:05:04]# is user02
bash: is: command not found...
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐