Linux Shell基础与用户/组管理详解(从入门到实战)
本文基于课堂笔记整理,涵盖 Shell 变量、环境变量、命令替换、引号使用,以及 Linux 用户和组管理的完整操作,适合初学者系统学习。
一、Shell 基础
1.1 变量定义与查看
在 Linux Shell 中,变量用于临时存储字符串值,变量值保存在当前会话的内存中,退出终端即丢失。
命名规则:
- 只能包含字母、数字、下划线
- 不能以数字开头
- 变量类型通常不需要显式声明
基本操作:
# 定义变量(两种方式等价)var1=key1declarevar1=key1# 引用变量(使用 $)echo$var1# 输出 key1# 拼接字符串first_name=facailast_name=zhangecho$last_name$first_name# zhang facai# 使用花括号限定变量名范围(避免歧义)echo${last_name}_$first_name# zhang_facai# 查看当前 Shell 中所有变量(含函数)setset|grepfirst_name# 过滤查看# 取消变量unsetfirst_nameecho$first_name# 空关于空格和引号:
- 多个空格在输出时会被压缩为一个
- 使用双引号可保留空格
echo"$first_name$last_name"# zhang facai变量大小写转换(declare特有):
declare-lname=James# 转为小写echo$name# jamesdeclare-uname=James# 转为大写echo$name# JAMES1.2 环境变量
环境变量是 Shell 内置的、用于控制运行环境的变量。常见的环境变量如下:
| 变量名 | 作用 |
|---|---|
EDITOR | 默认编辑器 |
PATH | 命令搜索路径 |
HOME | 当前用户家目录 |
USER | 当前用户名 |
PWD | 当前工作目录 |
LANG | 系统语言 |
PS1 | 命令行提示符格式 |
HISTTIMEFORMAT | 历史命令时间格式 |
示例:EDITOR
visudo# 默认使用 vi,无语法高亮exportEDITOR=/bin/vim visudo# 现在使用 vim# 或临时指定EDITOR=/bin/vim visudo示例:LANG
date# 中文输出exportLANG=en_US.utf8date# Mon Nov 7 13:38:55 CST 2022示例:PATH
echo$PATH# 误将 ls 移走,导致命令找不到mv/usr/bin/ls.ls# 报错:command not found# 恢复 PATH(临时)PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin# 将当前目录追加到 PATHexportPATH=$PATH:/rootls# 现在可以用当前目录下的 ls示例:PS1(提示符)
echo$PS1# 查看当前提示符格式PS1='[\u@\h \W \t]\$ '# 显示用户名、主机、当前目录、时间彩色提示符(写入/etc/bashrc或~/.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\] '示例:HISTTIMEFORMAT
exportHISTTIMEFORMAT="%F %T "history# 显示每条命令的执行时间1.3 变量持久化保存
变量默认只在当前 Shell 生效,若希望永久保存,需写入配置文件。
Login Shell 加载顺序(如通过 SSH 登录):
/etc/profile(系统级,所有用户)~/.bash_profile(用户级)~/.bashrc(用户级)/etc/bashrc(系统级,所有用户)
Non-login Shell 加载顺序(如执行bash命令):
~/.bashrc/etc/bashrc
# 系统级持久化echo'export LANG=en_US.utf8'>>/etc/profile# 用户级持久化echo'export EDITOR=vim'>>~/.bashrc1.4 命令替换
使用$(command)或反引号command将命令输出作为字符串。
echoToday is$(date+%A)echoThetimeis$(date+%M)minutes past$(date+%l%p).# 创建带日期的文件touchfile-$(date+%Y%m%d)经典计算 1+2+…+100:
# 生成序列并替换空格为 +echo{1..100}|tr' ''+'# 交给 $[] 计算echo$[$(echo{1..100}|tr' ''+')]# 输出 50501.5 保留字符字面含义
许多字符在 Shell 中有特殊含义,如需原样输出,可使用转义或引号。
\:取消后面单个字符的特殊含义""(双引号):保留变量替换、命令替换和转义,但压缩空格扩展''(单引号):保留所有字符的字面含义,不进行任何替换
echo\$PATH# 输出 $PATHusername=XieBaiQiecho"Welcome$usernameon$(date+%F)"# 正常替换echo'Welcome $username on $(date +%F)'# 原样输出# 多行输入(引号内可换行)echo"hello 1 hello 2 hello 3">hello.txt二、Linux 用户和组管理
2.1 用户概念
Linux 中的每个进程都以特定用户身份运行,每个文件都有属主和属组。系统通过UID(User ID)唯一标识用户,用户名为辅助标识。
三种用户类型:
- 超级用户(root):UID=0,拥有最高权限
- 系统用户:由系统服务使用,通常 UID 1~999(CentOS 7),不能交互登录
- 普通用户:UID >= 1000,日常操作使用
2.2/etc/passwd文件
每行代表一个用户,冒号分隔 7 个字段:
name:password:UID:GID:GECOS:directory:shell示例:
xianyu:x:1000:1000:software admin:/home/xianyu:/bin/bashpassword:实际密码加密后存在/etc/shadow,这里用x占位GID:用户主要组的 IDGECOS:用户描述信息(如全名)directory:用户家目录shell:登录后执行的程序,如/bin/bash,系统用户通常为/sbin/nologin
2.3/etc/group文件
每行代表一个组,冒号分隔 4 个字段:
group_name:password:GID:user_list示例:
wheel:x:10:xianyupassword:组密码,通常用x表示(实际加密在/etc/gshadow)user_list:属于该组的补充成员(用逗号分隔)
主要组:用户创建文件时的默认属组,由/etc/passwd中的 GID 决定。
补充组:用户额外加入的组,记录在/etc/group的user_list中。
查看用户所属组:
idxianyu# uid=1000(xianyu) gid=1000(xianyu) groups=1000(xianyu),10(wheel)2.4 用户管理命令
whoami, who, w, users
whoami# 当前登录用户who# 所有登录会话w# 详细信息(含负载、空闲时间)users# 仅列出用户名useradd(创建用户)
# 默认创建(UID自动分配,家目录 /home/用户名)useradduser01# 指定选项useradd-u8888-d/opt/user02-c"user for software"-gwheel-s/sbin/nologin user02# -u UID# -d 家目录# -c 描述信息# -g 主要组# -s 登录 shell# 创建无密码用户(图形界面可直接登录)useradd-p''tom新用户家目录模板来自/etc/skel/,创建时会复制其中的隐藏文件(.bashrc等)。
默认创建参数配置在/etc/login.defs。
usermod(修改用户)
# 修改 UID、家目录、shellusermoduser02-u1008-md/home/user02-s/bin/bash# usermod 修改已存在用户的属性# user02 要修改的目标用户名# -u 1008 修改用户 UID 为 1008# -md /home/user02 -m (与 -d 搭配使用) 将原家目录内容移动到新目录并创建新家目录;-d 指定新的家目录为 /home/user02# -s /bin/bash 修改用户登录后使用的默认 Shell 为 /bin/bash# 添加补充组(-a 表示追加,否则覆盖)usermod-aGuser01 user02# usermod 修改已存在用户的属性# -aG user01 -a (append) 表示以“追加”的方式修改附加组;-G 用于指定附加组(附属组)。两者结合意为:把用户 user02 追加到附加组 user01 中(注意:如果只用 -G 会覆盖掉之前所有的附加组,-aG 则是增加一个而不丢失原有的组)iduser02userdel(删除用户)
userdeluser03# 正常删除userdel-fuser02# 强制删除(即使进程占用)2.5 综合案例:手动创建用户
不借助useradd,手动添加用户zhangsan:
编辑
/etc/passwd,添加一行:zhangsan:x:1002:1002::/home/zhangsan:/bin/bash编辑
/etc/group,添加组:zhangsan:x:1002:编辑
/etc/shadow,添加密码条目(可复制其他用户的加密密码,或使用openssl passwd生成)准备家目录:
cp-r/etc/skel/ /home/zhangsanchown-Rzhangsan:zhangsan /home/zhangsan测试登录:
sshzhangsan@localhost
2.6 本地组管理
groupadd
groupaddadmingroupaddsysadmin-g2000# 指定 GIDgroupmod
groupmod--new-name admins admin# 重命名groupmod-g2002admins# 修改 GIDgroupdel
groupdelsysadmingroupmems(管理组成员)
# 添加成员groupmems-gadmins-axianyu# 列出成员groupmems-gadmins-l# 删除成员groupmems-gadmins-dxianyu# 清空所有成员groupmems-gadmins-p2.7 管理用户密码
/etc/shadow文件
每行 9 个字段,冒号分隔:
login:encrypted_password:last_change:min:max:warn:inactive:expire:reservedlast_change:上次修改日期距 1970-1-1 的天数min:最小修改间隔(天)max:最大有效期(天)warn:过期前警告天数inactive:过期后仍可使用的宽限天数expire:账户绝对过期日期
chage(修改密码策略)
chage-lxianyu# 查看当前策略chage-M100xianyu# 最大有效期 100 天chage-m10xianyu# 最小间隔 10 天chage-d0xianyu# 强制下次登录改密码chage-E1970-1-1 xianyu# 账户过期(锁定)usermod 管理密码
# 直接设置密码(需用加密字符串,可从 /etc/shadow 复制)usermod-p'$6$...'xianyu# 删除密码(空密码)usermod-p''xianyu# 锁定/解锁usermod-Llaowang# 锁定usermod-Ulaowang# 解锁# 限制 shellusermod-s/sbin/nologin laowangpasswd 相关
passwd-dlaowang# 删除密码(可无密码登录)passwd-llaowang# 锁定(同 usermod -L)passwd-ulaowang# 解锁passwd-elaowang# 强制下次登录改密码2.8 常见故障模拟与解决
情景1:bash 提示符变为bash-4.2$
原因:/etc/bashrc被移动或损坏,导致 PS1 未加载。
解决:
mv/etc/bashrc{.ori,}# 恢复情景2:用户家目录被误删
登录时提示Could not chdir to home directory
解决:
cp-r/etc/skel/ /home/zhangsanchown-Rzhangsan:zhangsan /home/zhangsan情景3:家目录权限错误
提示Permission denied或权限不够
解决:
chmodu=rwx /home/zhangsanchown-Rzhangsan:zhangsan /home/zhangsan2.9 特殊技巧
增加一个 UID=0 的用户(获得 root 权限)
方法一:直接修改/etc/passwd,将用户的 UID 改为 0
方法二:
useradd-o-u0xianyu# -o 允许重复 UID此时 xianyu 与 root 共享 UID 0,拥有 root 权限,但仍是两个独立账户。
三、课后练习(自测)
- 变量命名规范有哪些?
- 如何定义和查看变量?举例。
- 环境变量
PATH、PS1、LANG的作用是什么? - 命令替换如何使用?举例计算 1~100 的和。
- 单引号、双引号、反斜杠的区别是什么?
/etc/passwd和/etc/group各包含哪些字段?- 如何创建用户并指定 UID、家目录、描述信息、shell?
- 如何修改用户的主要组和补充组?
- 如何强制用户下次登录修改密码?如何锁定用户?
- 手动创建用户需要修改哪几个文件?如何准备家目录?