FHS、bash与用户权限

本文主要内容:FHS,文本查看、文件与目录管理命令,Bash特性,包括管道、重定向、命令历史、别名、变量等,以及Globbing,用户与权限管理。

文章目录

一、FHS

0. 文件系统概念

计算机实质上就是处理数据的设备,这些数据在存储介质中是以文件(File)的形式存在的,而具体该如何保存,以及如何对硬件进行逻辑抽象管理,使其可以保存,就是文件系统的功能之一。

计算机的文件系统是一种存储和组织计算机数据的方法,它使得对其访问和查找变得容易,文件系统使用文件和树形目录的抽象逻辑概念代替了硬盘和光盘等物理设备使用数据块的概念,用户使用文件系统来保存数据不必关心数据实际保存在硬盘(或者光盘)的地址为多少的数据块上,只需要记住这个文件的所属目录和文件名。在写入新数据之前,用户不必关心硬盘上的那个块地址没有被使用,硬盘上的存储空间管理(分配和释放)功能由文件系统自动完成,用户只需要记住数据被写入到了哪个文件中。

广义角度来讲,Linux系统是有底层的Kernel与上层Application组成。其在计算机启动之前也是以文件的形式存在于外存中,而这些文件保存在外存(以下称为磁盘)的何处位置,Linux的众多发行组织均可以自定义。如此对于用户的学习和使用而言是极为不便的,亦不利于其传播。鉴于此,Linux Foundation(Linux基金会)定义了Linux发行版中,文件所应该遵从的组织方式,即FHS(Filesystem Hierarchy Standard,文件系统层级标准) 1

1. 根文件系统

该规范说明了系统上应该存在哪些目录,以及不同文件所应该保存的位置,以下为简要说明

目录 说明
/bin 所有用户可用的基本命令程序文件
/boot 引导加载器必须用到的各静态文件,如kernel、ramfs(initrd),以及grub(bootloader)等
/dev 设备文件与特殊文件
/etc 系统程序的静态配置文件
/home 普通的家目录的集中位置;一般每个普通用户的家目录默认为此目录下与用户名同名的子目录
/lib 为系统启动或根文件系统上的应用程序(/bin,/sbin等)提供共享库,以及为内核提供内核模块
/lib64 特定字长系统上的库文件,如64位系统上为/lib64
/media 挂载点目录,通常用来挂载移动设备
/mnt 挂载点目录,通常挂载额外的临时文件系统
/opt, /options 附加应用程序的安装位置,可选
/proc 虚拟文件系统,用于为内核及进程存储其相关信息
/root 管理员的家目录,可选
/run 存放动态的,不持久的应用程序运行数据
/sbin 供管理员使用的工具程序
/srv 系统上运行的服务用到的数据
/sys sysfs虚拟文件系统提供了一种比proc更为理想的访问内核数据的途径;其主要作用在于为管理Linux设备提供一种统一模型的的接口
/tmp 临时文件
/usr 全局共享的只读数据路径
/var 频繁发生变化的文件
/misc 备用目录,可选
/selinux SELinux(Security Enhanced Linux)相关的安全策略等信息的存储位置
[root@localhost ~]# ls /
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

2. /usr目录层级

usr意为universal shared read-only file,全局共享只读文件,即该目录可以在所有遵循FHS的主机间共享(只读)

目录 说明
/usr/include C程序头文件
/usr/bin 普通用户命令
/usr/sbin 供管理员使用的命令
/usr/lib 库文件
/usr/lib<qual> 特定字长系统上的库文件,如64位系统上为/usr/lib64
/usr/share 命令手册也和自带文档等架构特有的文件的存储位置,例如doc, man等
/usr/X11R6 X-Window程序的安装位置(可选)
/usr/src 程序源码文件的存储位置
/usr/local 第三方软件的安装路径,也是一个独立层级
/usr/games 游戏或教育程序

/usr/local:local目录层级

该目录也是一个独立的层级,其中有bin,sbin等目录,如下内容引用自 https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#USRLOCALLOCALHIERARCHY

The /usr/local hierarchy is for use by the system administrator when installing software locally. It needs to be safe from being overwritten when the system software is updated. It may be used for programs and data that are shareable amongst a group of hosts, but not found in /usr.
Locally installed software must be placed within /usr/local rather than /usr unless it is being installed to replace or upgrade software in /usr.

Directory Description
bin Local binaries
etc Host-specific system configuration for local binaries
games Local game binaries
include Local C header files
lib Local libraries
man Local online manuals
sbin Local system binaries
share Local architecture-independent hierarchy
src Local source code

3. /var目录层级

/var contains variable data files. This includes spool directories and files, administrative and logging data, and transient and temporary files.
Some portions of /var are not shareable between different systems. For instance, /var/log, /var/lock, and /var/run. Other portions may be shared, notably /var/mail, /var/cache/man, /var/cache/fonts, and /var/spool/news.
/var is specified here in order to make it possible to mount /usr read-only. Everything that once went into /usr that is written to during system operation (as opposed to installation and software maintenance) must be in /var.
If /var cannot be made a separate partition, it is often preferable to move /var out of the root partition and into the /usr partition. (This is sometimes done to reduce the size of the root partition or when space runs low in the root partition.) However, /var must not be linked to /usr because this makes separation of /usr and /var more difficult and is likely to create a naming conflict. Instead, link /var to /usr/var.
Applications must generally not add directories to the top level of /var. Such directories should only be added if they have some system-wide implication, and in consultation with the FHS mailing list.2

目录 说明
/var/log 日志目录及文件
/var/lock 锁文件
/var/run 运行中的进程相关的数据,通常用于存放进程的PID文件
/var/cache 应用程序缓存数据目录
/var/lib 应用程序状态信息数据
/var/local 专用于为/usr/local下的应用程序存储可变数据
/var/opt 专用于为/opt下的应用程序存储可变数据
/var/spool 应用程序数据池
/vat/tmp 保存系统两次重启之间产生的临时数据

4. /sys目录内容

/sys 下的子目录 所包含的内容
/sys/devices 这是内核对系统中所有设备的分层次表达模型,也是 /sys 文件系统管理设备的最重要的目录结构,下文会对它的内部结构作进一步分析;
/sys/dev 这个目录下维护一个按字符设备和块设备的主次号码(major:minor)链接到真实的设备(/sys/devices下)的符号链接文件,它是在内核 2.6.26 首次引入;
/sys/bus 这是内核设备按总线类型分层放置的目录结构, devices 中的所有设备都是连接于某种总线之下,在这里的每一种具体总线之下可以找到每一个具体设备的符号链接,它也是构成 Linux 统一设备模型的一部分;
/sys/class 这是按照设备功能分类的设备模型,如系统所有输入设备都会出现在 /sys/class/input 之下,而不论它们是以何种总线连接到系统。它也是构成 Linux 统一设备模型的一部分;
/sys/block 这里是系统中当前所有的块设备所在,按照功能来说放置在 /sys/class 之下会更合适,但只是由于历史遗留因素而一直存在于 /sys/block, 但从 2.6.22 开始就已标记为过时,只有在打开了 CONFIG_SYSFS_DEPRECATED 配置下编译才会有这个目录的存在,并且在 2.6.26 内核中已正式移到 /sys/class/block, 旧的接口 /sys/block 为了向后兼容保留存在,但其中的内容已经变为指向它们在 /sys/devices/ 中真实设备的符号链接文件;
/sys/firmware 这里是系统加载固件机制的对用户空间的接口,关于固件有专用于固件加载的一套API,在附录 LDD3 一书中有关于内核支持固件加载机制的更详细的介绍;
/sys/fs 这里按照设计是用于描述系统中所有文件系统,包括文件系统本身和按文件系统分类存放的已挂载点,但目前只有 fuse,gfs2 等少数文件系统支持 sysfs 接口,一些传统的虚拟文件系统(VFS)层次控制参数仍然在 sysctl (/proc/sys/fs) 接口中中;
/sys/kernel 这里是内核所有可调整参数的位置,目前只有 uevent_helper, kexec_loaded, mm, 和新式的 slab 分配器等几项较新的设计在使用它,其它内核可调整参数仍然位于 sysctl (/proc/sys/kernel) 接口中 ;
/sys/module 这里有系统中所有模块的信息,不论这些模块是以内联(inlined)方式编译到内核映像文件(vmlinuz)中还是编译为外部模块(ko文件),都可能会出现在 /sys/module 中:
● 编译为外部模块(ko文件)在加载后会出现对应的 /sys/module/<module_name>/, 并且在这个目录下会出现一些属性文件和属性目录来表示此外部模块的一些信息,如版本号、加载状态、所提供的驱动程序等;
● 编译为内联方式的模块则只在当它有非0属性的模块参数时会出现对应的 /sys/module/<module_name>, 这些模块的可用参数会出现在 /sys/modules//parameters/<param_name> 中,
●● 如 /sys/module/printk/parameters/time 这个可读写参数控制着内联模块 printk 在打印内核消息时是否加上时间前缀;
●● 所有内联模块的参数也可以由 “<module_name>.<param_name>=” 的形式写在内核启动参数上,如启动内核时加上参数 “printk.time=1” 与 向 “/sys/module/printk/parameters/time” 写入1的效果相同;
● 没有非0属性参数的内联模块不会出现于此。
/sys/power 这里是系统中电源选项,这个目录下有几个属性文件可以用于控制整个机器的电源状态,如可以向其中写入控制命令让机器关机、重启等。
/sys/slab (对应 2.6.23 内核,在 2.6.24 以后移至 /sys/kernel/slab) 从2.6.23 开始可以选择 SLAB 内存分配器的实现,并且新的 SLUB(Unqueued Slab Allocator)被设置为缺省值;如果编译了此选项,在 /sys 下就会出现 /sys/slab ,里面有每一个 kmem_cache 结构体的可调整参数。对应于旧的 SLAB 内存分配器下的 /proc/slabinfo 动态调整接口,新式的 /sys/kernel/slab/<slab_name> 接口中的各项信息和可调整项显得更为清晰。3

5. 其他说明

设备文件

  • 块设备(b)
  • 字符设备(c)
  • 设备号:对设备文件使用ls -l查看时,显示文件大小的位置显示为2个数字,即主设备号(major number)与次设备号(minor number)
    • 主设备号,用于标识设备类型,进而确定要加载的驱动程序
    • 次设备号,用于标识同一类型中的不同的设备;

如:

[root@localhost ~]# ls -l /dev
total 0
crw-rw----. 1 root video    10, 175 Dec 28 22:21 agpgart
crw-------. 1 root root     10, 235 Dec 28 22:21 autofs
drwxr-xr-x. 2 root root         180 Dec 28 22:21 block
drwxr-xr-x. 2 root root          80 Dec 28 22:21 bsg
crw-------. 1 root root     10, 234 Dec 28 22:21 btrfs-control
drwxr-xr-x. 3 root root          60 Dec 28 22:21 bus
lrwxrwxrwx. 1 root root           3 Dec 28 22:21 cdrom -> sr0
drwxr-xr-x. 2 root root         100 Dec 28 22:21 centos
drwxr-xr-x. 2 root root        3060 Dec 28 22:21 char
crw-------. 1 root root      5,   1 Dec 28 22:21 console
lrwxrwxrwx. 1 root root          11 Dec 28 22:21 core -> /proc/kcore
drwxr-xr-x. 6 root root         140 Dec 28 22:21 cpu

/etc中常见目录

  • /etc/opt:/opt下程序的配置文件
  • /etc/sysconfig: 系统级别应用配置
  • /etc/init.d: 系统服务脚本
  • /etc/X11:X协议相关配置文件
  • /etc/sgml:SGML相关配置文件
  • /etc/xml:XML相关配置文件

库文件

  • 在/lib与/lib64中保存有共享库文件
  • 静态库:.a文件,直接链接到程序的地址空间中,作为程序的一部分额运行,便于程序单独管理
  • 动态库:.so(shared object)文件,即使有多个程序要使用,在内存中也只有一份
  • libc.so.*:动态链接的C库
  • ld*:运行时链接器/加载器
  • modules:内核模块文件存储目录

Linux上的应用程序的组成部分总结

  • 二进制程序: /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin
  • 库文件:/lib, /lib64, /usr/lib, /usr/lib64, /usr/local/lib, usr/local/lib64
  • 配置文件:/etc, /etc/DIRECTORY, /usr/local/etc
  • 帮助文件:/usr/share/man, /usr/share/doc, /usr/local/share/man, /usr/local/share/doc

二、一些基础命令

1. 目录与文件管理命令

cp

cp以为copy,即复制,用于复制文件或目录,格式:

cp SRC... DEST
	若SRC是一个文件
		若DEST不存在:创建此文件,并复制源文件的数据流至DEST中
		若DEST存在:覆盖,此时建议使用-i选项
		若DEST存在,且是个目录:复制源至目标目录中并保持源文件名

	若SRC有多个文件
		若目标存在,且是一个文件,报错
		若目标存在,且是一个目录:复制个文件至目标目录中,并保持原名
		若目标不存在,报错

	若SRC是只有一个且是目录(cp目录默认只复制文件,不会复制目录)
		若目标是一个文件且存在,报错
		若目标不存在:创建新目录
		若目标存在且是目录:复制源目录至目标目录中,且保持原名

常用选项

选项 描述
-R, -r, --recursive copy directories recursively,递归复制一个目录及其目录下所有位文件(包括子目录)
-f, --force 强行覆盖
-i, --interactive 交互式复制,如提醒用户是否覆盖已存在的数据
-p same as --preserve=mode(权限),ownership(属主属组),timestamps(时间戳),保留文件的属主、属组、权限以及时间戳
-a, --archive same as -dR,archive(归档),保留文件所有属性,常用于备份
-d,–no-dereference,–preserv=links 不追踪符号链接
–preserve[=ATTR_LIST] ATTR_LIST
- - - - mode:权限
- - - - ownership:从属关系(属主属组)
- - - - timestamps:时间戳
- - - - links:链接属性
- - - - xattr:扩展属性
- - - - context:安全上下文
- - all:以上所有
-L, --dereference always follow symbolic links,复制链接指向的文件(默认如此)
-P, --no-dereference never follow symbolic links in SOURCE ,保持链接
-d same as --no-dereference --preserve=links,当源文件为连接文件时,复制链接文件本身而非其指向的源文件

mv

mv意为move,即移动,可用于移动文件位置,或文件重命名。使用格式如下:

mv [OPTION]... SOURCE... DIRECTORY
	如果源和目标的路径相同,只是文件名不同,则为重命名

	[OPTION]
		-i		prompt before overwrite 提示复盖(默认管理员命令别名中存在)
		-f		do not prompt before overwriting 强制覆盖,不提示
		-t, --target-directory=DIRECTORY
		格式:	mv -t DEST SRC

mv可以直接移动目录,而无需-r选项

install

install即安装,可用于复制文件并定制其属性,常用格式

单文件复制
	install [OPTION]... [-T] SOURCE DEST

把多个文件复制到一个目录中:
	install [OPTION]... SOURCE... DIRECTORY
	install [OPTION]... -t DIRECTORY SOURCE... 

创建目录
	install [OPTION]... -d DIRECTORY...

[OPTION]
	-m=MODE		指定权限,默认为755
	-o=OWNER		指定属主
	-g=GROUP		指定属组

mktemp

mktemp意为make temporary,可创建临时文件或目录。常见用法如下:

mktemp [OPTION]... [TEMPLATE]
	[OPTION]
		-d		创建临时目录
		
	[TEMPLATE]
		指定要创建的临时文件或目录的名称,需要至少包含3个“X”

如:

[root@localhost ~]# mktemp /tmp/mytmp
mktemp: too few X's in template ‘/tmp/mytmp’
[root@localhost ~]# mktemp /tmp/mytmpXXXX
/tmp/mytmp8wQ7
[root@localhost ~]# mktemp /tmp/mytmpXXXXXXXXX
/tmp/mytmp6CwrEUrFN
[root@localhost ~]# mktemp /tmp/mytmpX2X3X4X5X6X
mktemp: too few X's in template ‘/tmp/mytmpX2X3X4X5X6X’

mkdir

mkdir即make directory,创建空目录,用法如下:

 mkdir [OPTION]... DIRECTORY...
 	[OPTION]
		-p, --parents
			no error if existing, make parent directories as needed
			参数中路径的最后一个节点才是要创建的目录,即路径基名才为命令的作用对象
			基名之前的路径须存在,若路径不存在可使用该选项创建
			
		-v, --verbose
			print a message for each created directory
		
		-m MODE		创建目录时直接指定权限

rmdir

rmdir意为remove directory,用于移除一个空目录

rmdir [OPTION]... DIRECTORY...
	[OPTION]
		-p, --parents		Remove DIRECTORY and its ancestors
			删除某目录后,若其父目录为空,则一并删除,依次类推
			
		-v					显示详细信息

tree

tree意为树,我们通常将Linux目录结构称为倒置的树状结构,使用该命令可展示该结构,命令参数:

参数 说明
-L level 指定显示层级数目
-d 只显示目录
-P pattern 只显示由指定的pattern匹配到的路径

如:

[root@localhost ~]# tree -dL 1 /
/
├── bin -> usr/bin
├── boot
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64 -> usr/lib64
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── srv
├── sys
├── tmp
├── usr
└── var

19 directories

rm

rm为remove,可移除文件或目录,该命令常用选项较少,但非常危险,请谨慎操作:

  • -r, -R, --recursive:递归删除
  • f, --force:强制删除
  • -i:交互模式,在删除每一个文件前询问是否删除

由于管理员使用该命令风险较高,故mv、rm、cp等默认都为管理员用户设置了命令别名4,用作提醒。

另外,建议所有不用的文件建议不要直接删除,而是移动至某个专用目录(模拟回收站)

2. 文本查看命令

cat、tac

这两个命令之前已有介绍,这里为了内容完整在此处列出,详见 https://blog.csdn.net/xiyangyang410/article/details/85043737#cat_458

head

head意为头,顾名思义,可查看文本文件的前几行,默认为10

head [OPTION]... [FILE]...
	[OPTION]
		-c #: 指定获取前#字节
		
		-n #: 指定获取前#行
			-#:n可省略

如:

[root@localhost ~]# head -5 /etc/fstab

#
# /etc/fstab
# Created by anaconda on Wed Dec 19 20:12:26 2018
#
[root@localhost ~]# head -c 50 /etc/fstab

#
# /etc/fstab
# Created by anaconda on Wed Dec 1[root@localhost ~]#

该命令在执行完成后不会自动换行

tail

tail即尾部,同样,可用于查看文本文件的末尾几行,默认为10

tail [OPTION]... [FILE]...
	[OPTION]
		-c #: 指定获取后#字节
		-n	# 显示后#行
			-#:n可省略
			
		-f	显示文件尾部,不退出,等待显示后续追加至此文件的新内容,通常用来监视日志

more

more意为更多的,其命令手册解释为: file perusal filter for crt viewing,可用于显示文本文件,命令使用方式同man命令。与之不同的是,该命令在文件显示至尾部后,将会自动退出。

less

less命令的同发与man命令相同,这里不再赘述。

  • less与more的不同之处在于less命令在显示到文件尾部后不会自动退出,而more将会自动退出

三、bash基础特性

1. 命令历史

使用方式

bash会保存的过去曾经执行过的命令,在当前shell进程中,保存在内存缓冲区中;

在用户的家目录下有一个**.bash_history**的隐藏文件,在用户正常退出时,内存缓冲区中的命令历史会追加到该文件中

  • Linux文件系统的另一特性:以点号开头的文件为隐藏文件,使用ls -a查看

用户在登陆时,系统会读取 ~/.bash_history 文件中记录下的命令

	使用上下箭头键可以翻看此前曾经执行过的命令

可通过使用history命令查看命令历史

调用命令历史列表中的命令

按键 操作
!n 执行命令历史中的第n条命令
!-n 执行命令历史中倒数第n条命令
!! 执行上一条命令
!STRING 执行命令历史中最近一个以STRING开头的命令(命令的重复执行有时候需要依赖于幂等性)
!$ 引用上一个命令的最后一个参数
ESC, . (按下ESC后,松开按.),引用上一个命令的最后一个参数
Alt+. 引用上一个命令的最后一个参数(远程终端可能不支持)

命令:history

history,即历史,Display the history list with line numbers,用法:

history [-c] [-d offset] [n]
history -anrw [filename]
history -ps arg [arg...]

参数
	-c					清空命令历史
	-r					从文件读取命令历史到历史列表中
	-w					把历史列表中的命令追加到历史文件中
	-d OFFSET [n]		删除指定位置的命令
	-a					追加当前会话的命令历史到历史文件中
	#					显示历史中最近的#条命令

相关环境变量

  • PATH:命令搜索路径
  • HISTSIZE:命令历史缓冲区大小
    • 在RedHat系统上默认是1000
  • HISTFILE:命令历史文件
  • HISTFILESIZE:命令历史文件中可以保存的命令的个数
  • HISTCONTROL:控制命令历史的记录方式
    • ignoredups 忽略重复的命令,连续相同的命令才为重复
    • ignorespace 以空格开头的命令不会被记录
    • ignoreboth 同时具有以上两个值的特性

2. bash的补全特性

我们在bash中输入时,可以通过敲Tab键来对我们的键入进行补全操作。

路径补全

按Tab可以补全以当前输入字符串开头的路径,若有多个,按两次Tab可以显示所有以该字符串开头的路径,若没有指出路径,则为当前目录。

该操作由bash搜索文件系统实现

命令补全

shell程序在接受到用户执行命令的请求,分析完成后,最左侧的字符串会被当做命令。在其搜索命令时,先搜索内部命令,而后将根据PATH坏境变量这设定的目录,自左而右逐个搜索目录下的文件名。

按Tab可以补全以当前输入字符串开头的命令,若有多个,按两次Tab可以显示所有以该字符串开头的命令,在PATH环境变量下搜索补全。

PATH环境变量是一组有冒号分隔的路径:

[root@localhost ~]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

由于进程在发起之前,其程序文件都是保存于计算机上的某位置,而我们之所以在键入命令时不必每次都输入命令的完整路径(即位置)就可以将其发起为一个进程(即运行命令),就是因为PATH环境变量。

3. 命令行展开

花括号展开

bash的*花括号展开特性可承载一个以逗号分隔的路径列表,并能够将其展开为多个,如:

[root@localhost ~]# mkdir -pv /mnt/test/{x/m,y}
mkdir: created directory ‘/mnt/test’
mkdir: created directory ‘/mnt/test/x’
mkdir: created directory ‘/mnt/test/x/m’
mkdir: created directory ‘/mnt/test/y’

以上命令同

[root@localhost ~]# mkdir -p /mnt/test/x/m
[root@localhost ~]# mkdir -p /mnt/test/y
[root@localhost ~]# mkdir -p /mnt/test/z

再如,使用展开用创建/tmp/test/a_b,a_c,d_b,d_c四个目录:

mkdir -pv /mnt/test/{a,d}_{b,c}

波浪线展开

  • ~:展开为用户的主目录
  • ~[USERNAME]:展开为指定用户的主目录

4. 快捷键

bash光标跳转的常用快捷键

按键 说明
Ctrl+a 跳到命令行首
Ctrl+e 跳到命令行尾
Ctrl+u 删除光标至命令行首的内容
Ctrl+k 删除光标至命令行尾的内容
Ctrl+← 向左跳转一个单词
Ctrl+→ 向右跳转一个单词
Ctrl+l 清屏,相当于clear命令
Ctrl+c 取消或终止
Ctrl+z 将当前命令送至后台,使用fg命令调回上次送至后台的进程

5. 命令别名

在我们经常使用某些冗长或不变记忆的命令时,可为其定义命令别名
如在Windows中,cls为清空屏幕命令,而在Linux中为clear,若更习惯使用“cls”,则可将cls定义为clear的别名,如此,在执行cls时,bash将执行clear;

再如,我们若需要经常编辑/etc/sysconfig/network-scripts/ifcfg-eno16777736文件时,在输入时比较繁琐,可将其定义为别名,使用alias命令:

alias

[root@localhost ~]# alias vimnet='vim /etc/sysconfig/network-scripts/ifcfg-eno16777736'

如此,在运行vimnet后,将等同于键入了vim /etc/sysconfig/network-scripts/ifcfg-eno16777736。

不带参数的alias命令可用于查看当前shell已经生效的名别名:

[root@localhost ~]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias vimnet='vim /etc/sysconfig/network-scripts/ifcfg-eno16777736'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

上文有提到,rm等命令已经默认为管理员用户设置了命令别名,这里可以查询。

若命令别名设置的与原命令相同,可在命令前加“\”(反斜线)来执行原命令。

unalias

若要撤销设定的命令别名,可使用unalias命令:

unalias COMMAND_ALIAS

撤销命令别名时只需指定别名即可

常用选项

  • -a:撤销所有别名

相关配置

使用alias设定的命令别名进队当前shell进程有效,可以在shell的配置文件中定义,使别名永久有效:

  • 仅对当前用户有效:~/.bashrc
  • 对所有用户有效:/etc/bashrc

若要使其立即生效,指定bash重新读取配置文件即可:

source /PATH/TO/CONFIG_FILE

该命令也可简写为.

. /PATH/TO/CONFIG_FILE

6. bash中的引号

引号,即为引用之意,bash中支持3种引用类型。

命令引用

使用反引号(``)引起来的内容将被当做命令执行,并将执行结果返回。
如,欲查看vim命令的课执行文件的类型:

[root@localhost ~]# which vim
/usr/bin/vim
[root@localhost ~]# file `which vim`
/usr/bin/vim: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked(uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x530e3b1a3084847f35bfddc8527f432c028b7ca0, stripped

另外,使用 $(COMMAND) 也可实现相同的效果。

强引用

使用单引号(’’)可进行强引用,即引号中的内容将会按字符返回,不会被解析为其他意义(转义字符除外),所见即所得,如:

[root@localhost ~]# var1=1
[root@localhost ~]# echo $var1
1
[root@localhost ~]# echo '$var1'
$var1

弱引用

使用双引号("")为若引用,引号中的内容将会被解析为变量,如:

[root@localhost ~]# var1=1
[root@localhost ~]# echo "$var1"
1
[root@localhost ~]# echo $var1
1
[root@localhost ~]# echo '$var1'
$var1

如上所示,我们一般可以省略双引号。

7. 变量

变量(Variable) 相信大家并不陌生,其实质上就是一段命名的内存空间。而在bash中,同样支持变量的概念。

bash中的变量类型

变量类型 说明
环境变量 作用域为当前shell进程及其子进程
本地变量 作用域为整个bash进程
局部变量 作用域为当前代码段(通常指函数)
位置变量 $1,$2,…用于让脚本在脚本代码中调用通过命令行传递给它的参数
特殊变量 保存某些特殊数据5
特殊变量
$0: 脚本名称本身
$?: 上一条命令的执行状态
  • 状态用数字表示:0-255
  • 成功:0
  • 失败:1-255
$$:脚本运行的当前进程ID
$!:Shell最后运行的后台进程的PID
$#: 参数数量
$*: 所有参数的一个字符串
$@:所有参数单独作为每个字符串
$1、$2…:位置变量,对应第一、第二个参数
关于$@与$*的区别:
只有在双引号中体现出来。假设在脚本运行时写了三个参数(分别存储在$1 $2 $3)则"$*" 等价于 “$1 $2 $3"(传递了一个参数);而“$@" 等价于 “$1” “$2” “$3”(传递了三个参数)

变量声明

bash中变量的命名规则同其他语言类似,变量名只能包含数字、字母和下划线,而且不能以数字开头,另外,变量赋值时不能使用$。

本地变量的声明

bash为弱类型,故在声明变量时不必指定变量类型(但这不代表这些变量没有类型),可直接使用如下形式声明变量:

[set] VARNAME=VALUE
	set可省略

使用不带参数的set命令可查看系统已定义的所有变量

只读变量的声明

readonly VARNAME
或
declare -r VARNAME

在声明时指定readonly,或使用declare -r,可声明只读变量(常量),由于其在声明后不可更改内容,需要在声明时进行初始化。

环境变量的声明

export VARNAME=VALUE
或
VARNAME=VALUE; export VARNAME
或
declare -x VARNAME
环境变量的查看
printenv
env
export

环境变量对当前shell及其子shell都有效

局部变量的声明

local VARNAME=VALUE

仅对局部代码生效

变量的引用

  • ${VARNAME} 不会引起混淆的话,{}可省略
  • “” 弱引用,其中的变量引用会被替换为变量值
  • ‘’ 强引用,其中的变量引用不会被替换为变量值,而保持原字符串

8. 重定向与管道

I/O重定向

Linux中一切皆文件,打开的文件都有一个FD(File Description)。即文件描述符,这里特别说明一下特殊的I/O文件:

  • 默认输出设备:标准输出,STDOUT,默认为monitor,描述符为1
  • 默认输入设备:标准输入,STDIN,默认为keyboard,描述符为0
  • 标准错误输出:错误信息,STDERR,默认为monitor,描述符为2

默认设备

  • 标准输入:键盘
  • 标准输出和错误输出:显示器

而I/O重定向就是改变数据输入来源或输出目标的操作。

输出重定向与错误输出重定向

  • > 覆盖输出

    • set -C : 禁止对已存在文件使用覆盖重定向
      • >|: 强行覆盖输出(即使设置了set -C)
    • set +C : 关闭上述功能
      • set命令可以使用+或-来设置或取消相关选项
  • >> 追加输出

  • 2> 重定向错误输出(覆盖输出)

  • 2>> 重定向错误输出(追加方式)

  • &> 覆盖重定向(标准输出与错误输出)

  • &>> 追加重定向(标准输出与错误输出)

[root@localhost ~]# echo 'hello world' > hello.out
[root@localhost ~]# cat hello.out
hello world
[root@localhost ~]# echo 'how are you' > hello.out
[root@localhost ~]# cat hello.out
how are you
[root@localhost ~]# echo 'new line' >> hello.out
[root@localhost ~]# cat hello.out
how are you
new line
[root@localhost ~]# ls /err 2> hello.out
[root@localhost ~]# cat hello.out
ls: cannot access /err: No such file or directory
[root@localhost ~]# lss /tmp 2>> hello.out
[root@localhost ~]# cat hello.out
ls: cannot access /err: No such file or directory
-bash: lss: command not found
[root@localhost ~]# ls / &>> hello.out
[root@localhost ~]# cat hello.out
ls: cannot access /err: No such file or directory
-bash: lss: command not found
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
标准输出和错误输出各自定向值不同位置
COMMAND > /path/to/file.out 2> /path/to/error.out
合并标准输出和错误输出为同一个数据流进行重定向
&> 覆盖重定向
&>> 追加重定向
COMMAND > /path/to/file.out 2> &1
COMMAND >> /path/to/file.out 2> &1
程序的执行状态返回值
Linux中的程序或指令在执行完成后,不只有执行结果(有的不会显示),还会有一个执行状态返回值(Return Code),用于标识该指令执行成功与否。
0表示执行成功,否则标识执行不成功,该值保存于变量$?中

输入重定向

  • < 输入重定向
  • << Here Document 在此处生成文档
    • <<后的为文档结束符,如:cat >> /tmp/myfile.txt << EOF

管道

管道(pipe)的作用为连接程序,实现将前一个命令的输出直接定向后一个程序当作输入数据流,即前一个命令的输出作为后一个命令的输入。用法格式为

COMMAND1 | COMMAND2 | COMMAND3 | ...

如:

[root@localhost ~]# echo 'hello world' | tr 'a-z' 'A-Z'
HELLO WORLD
Tips
  • 最后一个命令会在当前shell进程的子shell进程中执行

相关命令

tr

tr为translate的前2个字母,可用于转换或删除字符

tr [OPTION]... SET1 [SET2]
	将SET1中的字符替换为SET2的字符

	[OPTION]
		-d		delete characters in SET1, do not translate

该命令在执行时一般使用重定向,如:

tr 'ab' 'AB' < /etc/passwd			# 将/etc/passwd文件中的a或b转换成A或B

tr 'a-z' 'A-Z ' < /etc/passwd		# 将/etc/passwd文件中的小写字母转换成大写

tee

tee

如图,tee命令可将数据流分为“两份”,一份发送到标准输出,另一份可通过重定向输出到文件。

/dev/zero

/dev/null是使用软件模拟的特殊的设备文件

该设备被称为bit bucket,它就像一个垃圾桶,丢进去的数据都会消失。那这个设备有什么用呢?

我们知道程序的执行结果又两种,一种是正常的返回结果,另一种是程序的执行状态结果,用于标识程序是否正常执行。例如我们想知道用户“user1”是否存在,可以使用id命令6,而我们并不关心其本身信息,只是通过id命令的执行状态返回值判断其是否存在:

[root@localhost ~]# id user1 &> /dev/null
[root@localhost ~]# echo $?
1
[root@localhost ~]# useradd user1
[root@localhost ~]# id user1 &> /dev/null
[root@localhost ~]# echo $?
0

四、时间戳

1. 基础概念

数据是以文件的形式存储在磁盘上,除了文件的数据(Data)本身,在存储时还会保存一些其他信息,即元数据(Metadata)7,时间戳信息就是其中之一。

Linux中的时间戳有三个,即

  • 最近一次的访问时间(Access Time),atime
  • 最近一次的修改时间(Modify Time),mtime
  • 最近一次的改变时间(Change Time),ctime

这里说明一下mtime与ctime的区别,前面提到,文件在存储时,有Data与Metadata,他们存储在不同的区域

  • mtime为修改时间,指的是修改了文件Data区域的时间
  • ctime为改变时间,指的是修改了Metadata区域的时间(如文件名)

需要注意的是,文件的mtime改变后,ctime一定会改变,因为mtime存储在Metadata中

2. 相关命令

stat

stat意为状态,可查看文件或文件系统的状态,如:

[root@ ~]# cp /etc/fstab ./
[root@ ~]# stat fstab
  File: ‘fstab’
  Size: 541       	Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d	Inode: 206917765   Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2018-12-30 11:15:58.721775819 +0800
Modify: 2018-12-30 11:15:58.721775819 +0800
Change: 2018-12-30 11:15:58.721775819 +0800
 Birth: -

可以看到文件的相关元数据信息,其中的Access、Modify、Change即为其时间戳信息。

touch

touch意为触摸,用于改变文件的时间戳信息,用法如下:

touch [OPTION]... FILE...
	[OPTION]
		-a		change only the access time				只改变访问时间
		-c		do not create any files					如果文件不存在也不创建
		-m		change only the modification time		只改变修改时间
		-t STAMP
			use [[CC]YY]MMDDhhmm[.ss] instead of current time

没有只修改改变时间的选项,因为对文件做的任何修改(包括时间戳)都会改变文件的属性(改变时间)

若FILE不存在,touch命令会自动创建该文件,故可使用该命令来创建文件,使用-c指定若文件不存在也不创建。

五、Globbing

Globbing,通配,即通用匹配之意,是指用一些特殊的字符,使其不标识其本来的字面意义,而标识某一类字符集合,以此为 模式(Pattern) 进行字符匹配。

通配符 描述
* 任意长度的任意字符
? 任意单个字符
[] 匹配指定字符范围内的任意单个字符
[^] 指定范围以外的任意单个字符

关于范围,可使用如下方式表示,如

范围 描述
[abc] 从abc中匹配,注意:此通配不区分大小写
[a-m] 从a-m范围内匹配,注意:此通配不区分大小写
[0-9] 数字
[a-zA-Z] 字母
[[:space:]] 空白字符
[[:punct:]] 标点符号
[[:lower:]] 小写字符
[[:upper:]] 大写字母
[[:alpha:]] 大小写字母
[[:digit:]] 数字
[[:alnum:]] 数字和大小写字母
Tips
  • 指定范围是不区分大小写,而指定单个字母时区分
  • 外层[]表示匹配任意单个字符,里面为集合;
  • 也支持^,如[^[:digit:]]表示非数字;
  • 使用man 7 glob可查看相关帮助

字母开头,字母结尾,中间有空白字符:
[[:alpha:]]*[[:space:]]*[[:alpha:]]

显示/var目录下所有以l开头,以一个小写字母结尾,且中间出现至少一位数字的文件或目录;
# ls -d /var/l*[0-9]*[[:lower:]]

显示/etc目录下,以任意一位数字开头,且以非数字结尾的文件或目录;
# ls -d /etc/[0-9]*[^0-9]

显示/var目录下所有以l开头,以一个小写字母结尾,且中间出现一位任意字符的文件或目录;
# ls -d /vat/l?[[:lower:]]

显示/etc目录下,以任意一位数字开头,且以非数字结尾的文件或目录;
# ls -d /etc/[0-9]*[^0-9]

显示/etc目录下,以非字母开头,后面跟一个字母及其它任意长度任意字符的文件或目录;
# ls -d /etc/[^[:alpha:]][a-z]*

复制/etc目录下,所有以m开头,以非数字结尾的文件或目录至/tmp/brahming目录;
# cp -r /etc/m*[^0-9] /tmp/brahming

复制/usr/share/man目录下,所有以man开头,后跟一个数字结尾的文件或目录至/tmp/man/目录下;
# cp -r /usr/share/man/man*[0-9] /tmp/man

复制/etc目录下,所有以.conf结尾,且以m,n,r,p开头的文件或目录至/tmp/conf.d/目录下;
# cp -r /etc/[mnrp]*.com /tmp/conf.d

七、用户

1. 什么是用户

现代的计算机都是多任务(Multi-Tasks)多用户(Multi-Users) 的,早期的计算机由于各种原因,并不是每个人独立拥有一台计算机,而计算机用户的概念就可以用户标识每一位使用者。如今,这一概念已经普遍使用。

对于Linux系统而言,用户是系统进行资源分派的单位,其主要关注:

  • 认证(Authentication)
  • 授权(Authorization)
  • 审计(Accounting)

2. Linux用户

UID

UID(User ID),即用户ID,UID是系统用于标识用户的字符,用户输入的登录名(即用户名)也将会映射为UID进而有系统处理。

用户分类

  • 管理员:UID为0
  • 普通用户:UID:1-65535
    • 系统用户:UID:1-999
      • 在CentOS6中UID为1-499
      • 系统用户对守护进程获取系统资源进行权限分配,不允许登陆系统
  • 一般用户:1000-60000
    • 在CentOS7中为500-60000
    • 交互式登录

UID的范围规定在 /etc/login.defs文件中

UID与用户名的映射关系保存于文件 /etc/fstab

3. 组

什么是组

组(Group) 是用户的容器,若几个用户属于一个组,就有了这个组拥有的权限,可以说组是一个权限设定的容器。

GID

UID相同,GID(Grou ID) 即组ID,用于标识一个组。

组的分类

用户组类别①
管理员组:GID为0
普通组:GID:1-65535
  • 系统组:GID:1-499,在CentOS7中GID为1-999
  • 一般组:GID:500-60000,在CentOS7中GID为1000-60000
用户组类别②
基本组(主组):用户的默认组
附加组,额外组:默认组以外的其他组
用户组类别③
私有组:创建用户时,如果没有为其指定所属的组,系统会自动为其创建一个仅包含当前用户的且与当前用户同名的组,只包含一个用户
公共组:组内包含多个用户

4. 用户管理相关命令

useradd

useradd以为用户添加,用法如下:

useradd [options] USERNAME
	[options]
		-u UID				指定UID,其他用户尚未使用的
		-g GID				指定GID(基本组),组要事先存在,可为组名,也可为GID
		-G GID,...			指定GID(附加组),组要事先存在,可为组名,也可为GID,多个组之间使用逗号分隔
		-c "COMMENT"		指定注释信息
		-d,  --home  /PATH/TO/SOMEDIRECTORY
			指定家目录
			通过复制/etc/skel目录并重命名的方式实现
			若指定的目录事先存在,则不会为用户复制环境配置文件
		-s SHELL			指定shell
			/etc/shells指定了当前系统可用的安全shell
			默认为/etc/default/useradd 中的 SHELL 变量中指定的shell
		-m -k				强制为用户创建家目录,并且当-k选项启用时,将/etc/skel/下的文件复制到当前用户的家目录
		-M					不为用户创建家目录,即使/etc/login.defs中允许创建
		-r						添加一个系统用户
			不会用用户创建家目录
			默认shell为/sbin/nologin
		-D					显示创建用户的默认配置
		-D[options]			修改选项的值
			修改的结果保存于/etc/default/useradd文件中
		-f					指定账户非活动期限,指定-1则永不禁用

关于配置文件,后文将介绍

另外,也可使用adduser命令,该命令为useradd命令的符号链接

[root@ ~]# file `which adduser`
/usr/sbin/adduser: symbolic link to `useradd'

userdel

userdel即User Delete,删除用户,该命令用法较为简单:

userdel [options] USERNAME
	[options]
		-r		同时删除家目录,默认不会删除

usermod

usermod为User Modify,可用于更改用户的属性,用法为:

usermod [options] USERNAME
	[options]
		-u				修改UID
		-g				修改基本组
		-G				修改附加组,如果用户此前已经有附加组,修改后会覆盖此前的附加组
			-a -G		追加(append)附加组
		-c				修改注释信息
		-d				修改家目录,默认不会迁移用户的家目录,也不会创建指定目录
			-d -m			修改家目录并且将原来目录中的文件移动至修改后的目录
		-s				修改用户shell
		-l				修改用户登录名
		-L				锁定账号,锁定后无法登录
		-U				解锁账号
			passwd命令也可以锁定与解锁账户
			
		-e YYYY-MM-DD
			指明用户账号过期日期
			
		-f INACTIVE
			设定账户非活动期限

passwd

passwd即Password,密码之意,可用于更新用户的认证信息(如密码),用法如下:

passwd [OPTION] [USERNAME]
	[OPTION]
		--stdin		从标准输入读取用户密码
			例:
				echo "redhat" | passwd --stdin user3
		-l			锁定账号
		-u			解锁账号
			账户锁定后,/etc/shadow文件该账户对应条目密码字段前会多一个感叹号(!),可手动加上,以锁定用户
	
		-e DATE				过期期限
		-n mindays			指定最短使用期限
		-x maxdays			最大使用期限
		-w warndays			提前多少天开始警告
		-i inactivedays		非活动期限

		-d			删除用户密码
			红帽系统会禁止空密码用户登录
  • 不带参数的passwd命令可用于修改自己的密码
  • 只有管理员可以不输入原始密码而修改其他用户的密码
密码复杂性策略
1、 使用4中类型字符(大写字母,小写字母,数字,特殊字符)中至少3种;
2、 足够长,建议大于8位;
3、 使用随机字符串;
4、 定期更换;
5、 循环周期要足够大;

id

前文有提到,可使用id命令查看用户信息:

id [OPTION]... [USER]
	[OPTION]
		-u		仅显示有效的UID
		-g		仅显示基本组ID
		-G		所有组的GID(包括基本组可附加组)
		-r		显示真实ID
		-n		以上命令统与-n一起使用,则显示名称,而不是ID号

不带参数的id命令可用于查看自己的信息,如:

[root@ ~]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

su

su即switch user,可用于切换用户,在介绍命令用法之前,先介绍一下Shell类型。
站在用户的角度,Shell分为登录式Shell与非登录式Shell

  • 登录式Shell:正常通过某终端登录
  • 非登录式Shell:图形终端下打开的命令窗口(伪终端)、自动执行的shell脚本

su的选项:

su [options...] [-] [user [args...]]
	[options]
		-l:“su -l UserName”相当于“su - UserName”
		-c 'COMMAND':仅以指定用户的身份运行此处指定的命令
切换用户的方式
su UserName:非登录式切换,即不会读取目标用户的配置文件;
su - UserName:登录式切换,会读取目标用户的配置文件;完全切换;
Tips
root su至其他用户无须密码;非root用户切换时需要密码;
换个身份执行命令
su [-] UserName -c ‘COMMAND’

chage

chage以为change age,可修改用户的账号过期信息

chage [options] USER
	[options]
		-d		最近一次修改时间(YYYY-MM-DD)
		-E		账号的过期(禁用)时间(YYYY-MM-DD)
		-I		非活动时间,即用户锁定后允许用户修改密码的时间
		-m		密码最短使用期限
		-M		密码最长使用期限
		-W		警告时长
		-l		显示用户密码过期信息

chsh

该命令可修改用户的默认shell

whoami

查看自己的用户名

pwck

验证密码文件的完整性

grpck

验证组文件的完整性

chfn

修改用户的注释信息

5. 组管理相关命令

groupadd

groupadd可用于创建一个新组,用法为:

groupadd [options] group
	[options]
		-g GID		指定GID,如不指定,则为系统中最高GID+1
		-r			添加为系统组

groupdel

groupdel用于删除用户组

groupmod

groupmod可修改组信息,用法有groupadd相似:

groupmod [options] GROUP
	[options]
		-g GID					修改GID
		-n GRPNAME				修改组名

gpasswd

gpasswd拥有给组添加密码,用法:

gpasswd [OPTIONS] GROUPNAME
	[OPTIONS]
		-a USER			将USER添加至指定组中
		-d	USER		删除用户USER的以当前组为组名的附加组
		
		-A user1,user2,...	设置有管理权限的用户列表
		
		-M				Set the list of group members.
说明:
1、 用户创建的文件的属组为当前用户的基本组
2、 用户可以使用newgrp命令,将用户的基本组临时更换为其他组
  • newgrp GRPNAME
  • 使用exit,可以退出临时切换过去的组
  • 如果用户本不属于此组,则需要组密码
3、 若用户的附加组中没有该组,则需要输入组密码

newgrp

newgrp即new group,可临时切换指定组为用户的基本组

nwegrp [-] [group]
	-:会模拟用户重新登录以实现重新初始化其工作环境

6. 相关文件或目录

用户相关

/etc/passwd

该文件是用户信息数据库,每一行定义一个用户。以root为例,内容为:

[root@ ~]# head -1 /etc/passwd
root:x:0:0:root:/root:/bin/bash

该文件的每一行有7个字段,用于共同指定一个用户的相关信息,中间使用半角冒号(:)分隔,依次为用户名、密码、用户ID、用户私有组ID、用户注释、家目录、用户默认shell程序,即:

account:password:UID:GID:GECOS:directory:shell

字段 说明
account 登陆名
password 可以是加密的密码,也可以是占位符(man 8 pwconv查看)
UID the numerical user ID
GID 基本组(私有组)ID
GECOS 可选的,用户的注释(comment)信息
directory the user’s $HOME directory
shell 用户的默认shell(/etc/shells指定了当前系统可用的安全shell)

可使用man 5 passwd查看文件格式信息

/etc/shadow

该文件为真正的密码文件,主要保存认证口令,依然是每一行用于记录一个用户的信息,以root为例,内容为:

[root@ ~]# head -1 /etc/shadow
root:$6$ZoCI8lk/jgp94iAd$DoJAlzqhNm4rkITOB4Dk/C9xZIw2nyv6AwT6YFosfidI6g9bpEx1YrrRncQEpR9a97Z/m0WBuNer5ukS7znHc0:17884:0:99999:7:::

另外该文件还记录了用户密码的使用时间,如用户密码的最长使用天数、用户当前密码已经使用的天数、账户的失效时间、密码的非活动时间等,文件格式为:

login name:encrypted password:date of last password change:minimum password age:maximum password age:password warning period:password inactivity period:account expiration date:reserved field

各部分说明如下

字段 说明
login name 登录名
encrypted password 加密后的密码
date of last password change 自1970.1.1至上次修改密码经过的天数
minimum password age 密码最短使用天数
maximum password age 密码最长使用天数
password warning period 密码警告区间,即自上次修改密码至密码有效天数前的时间(天)
password inactivity period 密码非活动区间,及在用户密码过期之后、禁用之前的天数
account expiration date 账户过期时间,自1970.1.1至账户禁用的天数
reserved field 保留字段
关于加密后的密码(encrypted password)字段的说明:
该字段由3个$隔开,前两个$中间的1表示使用md5加密,第二个与第三个$中间为为加密的密码加的随机字符串(salt,即杂质),第三个$后面的为密码
用户在登登陆时,系统将用户输入的密码中加入该杂质,计算后与passwd中的比较

加密方式的标识8

ID Method
1 MD5
2a Blowfish (not in mainline glibc; added in some Linux distributions)
5 SHA-256 (since glibc 2.7)
6 SHA-512 (since glibc 2.7)

可使用man 5 shadow查看该文件格式信息

加密算法介绍
  • 对称加密:加密和解密使用同一个密码
    • DES(data encryption standard),3DES,AES(Advanced Encryption Standard)
  • 公钥加密:每个密码都成对出现,一个为公钥(public key),一个为私钥(secret key)
    • DSA(Digital Signature Algorithm),RSA
  • 单向加密,散列加密:也叫指纹加密,提取数据特征码,只能由明文(数据)得到密文,不可逆。常用于数据完整性校验
    • MD5,Message-Digest Algorithm 5,信息摘要
    • SHA1,Secure Hash Algorithm,安全hash算法

此处简单说明单向加密

单项加密特点:
1、 雪崩效应:即初始条件的微小改变,将会引起结果的巨大变化;
2、 定长输出;注意:输出的是16进制数字,而不是字符
常用的单项加密:
MD5: Message Digest,128位定长输出,由麻省理工学院人工智能实验室研发
SHA1: Secure Hash Algorithm,160 位定长输出
SHA224: 224位定长输出
SHA256: 256位定长输出
SHA384: 384位定长输出
SHA512: 512位定长输出

/etc/default/useradd

在/etc/default/useradd中定义了useradd命令的相关默认信息,以下为该文件内容:

[root@ ~]# cat /etc/default/useradd
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

useradd使用-D选项修改的内容将保存于该文件中

用户的当前shell保存在环境变量SHELL

/etc/skel/目录

/etc/skel/中有一些环境配置文件

  • .bash_profile 登录时应用的用户配置文件
  • .bashrc 切换shell时应用的用户配置文件
  • .bash_logout 注销时应用的用户配置文件

/etc/login.defs

/etc/login.defs文件中有PASS_MAX_DAYS, PASS_MIN_DAYS, PASS_MIN_LEN, PASS_WARN_AGE, UID与GID的最大最小数等默认参数

用户管理相关配置文件总结

File Description9
/etc/passwd User account information.
/etc/shadow Secure user account information.
/etc/group Group account information.
/etc/gshadow Secure group account information.
/etc/default/useradd Default values for account creation.
/etc/skel/ Directory containing default files.
/etc/login.defs Shadow password suite configuration.

组相关

/etc/group

该文件存储了组名与GID的映射关系,依然是使用冒号分隔,每行定义一个组,格式为:

group_name:password:GID:user_list
group_name:组名
password:密码,一般为密码占位符
GID:组ID
user_list:以此组为附加组的用户列表(用户的基本在保存于/etc/passwd)

/etc/gshadow

该文件与/etc/shadow类似,保存加密后的组密码,使用冒号分隔,每行定义一个组:
group name:encrypted password:administrators:members

八、权限

1. 基础概念

进程的安全上下文(Secure Context)

进程是用户操作计算机的代理,进程运行时,是以发起者的身份运行,进程能范围内那些文件,取决于进程本身的权限以及发起者的权限

权限应用模型

  • 进程的属主,是否与文件的属主相同:若相同,进程则以文件属主的权限来访问文件,否则
  • 进程的属主所属的组,是否其中之一与文件的属组相同,若相同,进程则以文件属组的权限来访问文件,否则
  • 进程则以文件的其他用户的权限来访问文件

权限

Linux权限有三种

读(Read),以r标识

写(Write),以w标识

执行(eXecute),以x标识

应用方式
文件
r: 可获取文件的数据,如可以使用类似cat等内容查看命令查看文件内容;
w: 可修改文件的数据,如可以使用编辑器修改其内容;
x: 可以在命令提示符下当做命令提交给内核运行,即可以将其发起一个进程;
目录
r: 可以对此目录执行ls以列出内部的所有文件;
w: 可修改此目录下的文件列表,即可以在此目录中创建、删除文件;
x: 可以使用cd切换进此目录,也可以使用ls -l查看目录内容的文件信息;
表示方式

在使用ls -l查看文件信息时,可以看到文件权限有三组10,分别对应属主、数组、其他用户。每一组有三位,用于标识是否具有该权限,即每一位的变化有两种,如此每一位可以使用一位二进制数字表示,每一组可以使用一位8进制数字表示,对应关系如下

权限位 二进制 八进制 意义
--- 000 0 无权限
--x 001 1 执行
-w- 010 2
-wr 011 3 写,执行
r-- 100 4
r-x 101 5 读,执行
rw- 110 6 读,写
rwx 111 7 读,写,执行

该位上有对应权限则为1,没有则为0,遂用三组八进制数字表示,分别表示属主、属组、其他用户的权限,如:

字符表示 二进制表示 八进制表示
rw-r----- 110100000 640
rwxr-xr-x 111101101 755
rw-rw---- 110110000 660
rwxrwxr-x 111111101 775

2. 权限掩码

什么是权限掩码

我们知道,一个文件(或目录)若所有用户都有权限进行所有操作,则为777,若所有用户都没有权限进行任何操作,则为000,然而在创建文件的时候,权限为644,这是为什么呢?

在我们进行创建的时候,系统将待创建对象的所有权限位置为1,而由于默认给一个文件执行权限是非常危险的,故在创建目录与文件时,默认给定的最大权限不同:

  • 文件:666
  • 目录:777

但是如此的默认权限给定方式显然也是不合适的,故有了权限掩码(Mode Mask) 的概念。掩码,也叫遮罩码,即为遮挡之意。

  • 创建文件时,默认权限为666 - 权限掩码
  • 创建目录时,默认权限为777 - 权限掩码

由于管理员与普通用户的权限不同,其默认的权限掩码也不相同,可使用umask命令查看

umask

umask是一个内部命令,用于显示或设置用户的权限掩码

由于设置权限掩码的命令名为umask,故我们也将权限掩码称为umask

不带参数的umask命令可以查看当前用户的umask

[root@localhost ~]# umask
0022
[root@localhost ~]# useradd user1
[root@localhost ~]# su user1
[user1@localhost ~]$ umask
0002
[user1@localhost ~]$ exit
logout
[root@localhost ~]# groupadd group1
[root@localhost ~]# useradd -g group1 user2
[root@localhost ~]# su user2
[user2@localhost root]$ umask
0022

返回4位数字,最高位为特殊权限的掩码,这里暂且不论11

由直接结果可知,管理员的umask默认为022,普通用户的默认umask:

  • 若用户名与其基本组组名相同,umask为002
  • 若用户名与其基本组组名不同,umask为022

有如下例子:

[user1@localhost ~]$ clear
[user1@localhost ~]$ id
uid=1000(user1) gid=1000(user1) groups=1000(user1) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[user1@localhost ~]$ umask 023
[user1@localhost ~]$ touch test.file
[user1@localhost ~]$ ll test.file
-rw-r--r--. 1 user1 user1 0 Dec 30 20:27 test.file
问题描述
umask设定为023,而普通用户在创建文件时,应使用666-023,故默认权限应为643,而此处为644?
原因
文件创建时,默认没有执行权限,若通过umask计算出来有,则为其权限+1

3. 权限管理命令

chown

chown意为change owner,可用于修改文件的属主或属组,用法如下:

# chown USERNAME file,...			修改属主

# chown :GRPNAME file,...			修改属组
# chown .GRPNAME file,...			修改属组

# chown USERNAME:GRPNAME file,...	修改属主属组
# chown USERNAME.GRPNAME file,...	修改属主属组

参数
	-R		递归修改,修改目录及其内部文件的属主
	--reference=/PATH/TO/SOMEFILE file,...
			reference,参考,将file的属主属组设置为与/PATH/TO/SOMEFILE相同

只有管理员才可以执行此命令

chgrp

chgrp为change group之意,用于修改文件的属组,用法为:

chgrp [OPTION]... GROUP FILE...
	[OPTION]
		--reference=RFILE
			参考目标文件的属组设定

chmod

chmod意为change mode,用于修改文件的权限信息,用法为:

chmod [OPTION]... MODE[,MODE]... FILE...
	操作三类用户的权限,使用8进制形式
		例:	chmod 775 /tmp/abc
				(75==075, 5==005)
	
chmod [OPTION]... OCTAL-MODE FILE...
	操作指定类别用户的权限,使用u,g,o,a来赋权,可以基于=或+/-来进行
	
[OPTION]... 
	--reference=RFILE FILE...
		参照其他文件的权限为当前文件赋权
			
	-R: 递归修改,修改目录及其内部文件的权限(目录下的符号链接除外)

chmod [USER_TYPE]+|-|=MODE file,...
	修改某类用户或某些用户权限
		[USER_TYPE]
			u: owner 属主
			g: group 属组
			o: other 其他用户
			a: all 所有用户

		=:操作指定类别用户的权限
		+/-:操作指定类别用户的单个权限
	例:
		chmod o=rx /tmp/abc	 修改其他用户的权限为r-x
		chmod gu=rx /tmp/abc 修改属主属组的权限为r-x
		chmodu-x /tmp/abc 去掉属主的执行权限
		chmod u+x,g-x /tmp/abc
		chmod a+x /tmp/abc 修改三类用的权限(此处为加执行权限)
			a可以省略,写成chmod +x /tmp/abc 

  1. 目前的最新版为FHS3.0,详见 https://refspecs.linuxfoundation.org/fhs.shtml ↩︎

  2. 引用自 https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#THEVARHIERARCHY ↩︎

  3. 表格内容引用自 https://www.ibm.com/developerworks/cn/linux/l-cn-sysfs/ ↩︎

  4. 后文会详细介绍命令别名 ↩︎

  5. 关于特殊变量后续会详细介绍 ↩︎

  6. 关于用户管理类命令后文将介绍 ↩︎

  7. 后续将详细介绍 ↩︎

  8. 可使用man 3 crypt查看 ↩︎

  9. 表格摘自USERADD(8)-FILES ↩︎

  10. 详见 https://blog.csdn.net/xiyangyang410/article/details/85043737#ls_387 ↩︎

  11. 后续将介绍 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章