写在正文前,为非计算机专业的人提供一个提前的知识整理机会。
电脑的五大组成单元:输入单元、输出单元、CPU内部的控制单元、算术逻辑单元和内存。
0/1这个二进制的单位我们称为位(bit,亦称比特)。
但是位实在是太小了,所以在存储数据时,每份简单的数据都会使用到8个位的大小来记录,因此定义出字节(Byte)这个单位,它们的关系对应如下:
在早期的CPU设计中:
外频是指CPU与外部部件进行数据传输时的速度;
倍频是指CPU内部用来加速工作性能的一个倍数。
BIOS
BIOS(Basic Input Output System)是一个程序,这个程序是写死到主板上面的一个存储芯片中,这个存储芯片在没有通电时也能够记录数据,这就是只读存储器(Read Only Memory,ROM)。
补一个接口知识:
扇区(sector):磁盘的最小物理存储单位。
磁道(track):同一个同心圆的扇区组合成的圆。
柱面(cylinder):所有碟片上面的用一个磁道可以组合成所谓的柱面。
机械硬盘(Hard Disk Drive,HDD):需要驱动马达去转动碟片。先知道数据在哪个扇区上面,然后命令马达开始转,再让磁头去读取正确的数据。缺点是:磁盘读取延迟。
固态硬盘(Solid State Drive,SSD):最大好处是没有马达不需要转动,而是通过闪存直接读写的特性,因此除了没数据延迟且快速之外,还很省电。
南北桥:
(1)北桥:负责连接速度较快的CPU、内存与显卡等组件;现在大多数北桥整合到CPU中了。
(2)南桥:负责连接速度较慢的设备接口,包括硬盘、USB设备、网卡等。
扩展卡数据需要先进入南桥跟大家抢带宽,之后要传向CPU时,还得要通过CPU与南桥的通信管道,那条管道称为DMI2.0总线。
扩展卡装在哪个插槽上面,对性能而言也是影响很大的。所以插卡时,请详情阅读主板上面的逻辑图例,尤其是CPU与南桥通信的带宽方面,特别重要。
CMOS主要的功能为记录主板上面的重要参数,包括系统时间、CPU电压与频率、各项设备的I/O地址与IRQ等,由于这些数据的记录需要用电,因此主板上面才有电池。
BIOS是写入到主板上某一块flash或EEPROM的程序,它可以在计算机启动的时候执行,以加载CMOS当中的参数,并尝试调用存储设备中的引导程序,进一步进入操作系统当中。
**Tips:**如果公司需要一台服务器的话,建议不要自行组装,买品牌电脑的服务器比较好。速度的快慢与整体系统的最慢的那个设备有关。
API:应用程序编程接口(Application Programming Interface,API)。
Linux是具有“可移植性”的。
几乎所有的硬件设备文件都在/dev这个目录内,比如/dev/sda、/dev/sr0等。
Linux内的所有数据都是以文件的形式来呈现,整个Linux系统最重要的地方就是在于目录树结构。
目录树结构(directory tree)就是以根目录为主,然后向下呈现为分支状的目录结构的一种文件架构。
整个目录树结构最重要的就是那个根目录(root directory)。根目录的表示方法为一条斜线**“/”**,所有的文件都与目录树有关。
挂载(mount):所谓挂载就是利用一个目录当成进入点,将磁盘分区的数据放置在该目录下;也就是说进入该目录就可以读取该分区的意思。
本书采用的是CentOS 7.x,我用的虚拟机是Ubuntu,仁者见仁吧
**-ls**命令
-ls //用于显示指定工作目录下之内容(列出目前工作目录所含之文件及子目录)
简单好用的计算机:bc
进入:直接输入bc
退出:输入quit
[Tab]
[Ctrl]-c
注意,Linux下的[Ctrl]-c不是代表复制,而是用来中断正在运行的命令。
[Ctrl]-d表示键盘输入结束,相当于exit。
使用 –help 可以将该命令的用法做一个大致的了解,类似于说明手册,查阅命令的使用方法。
其中,man 是manual(操作说明)的简写。
以 date 命令为例,执行man date,可以清楚的看到date命令的说明。
进入man命令的功能后,按下【空格键】往下翻页,可以按下【q】按键来离开man的环境。
【DATE(1)】代表的是:“一般用户可以使用的命令”的意思。表格如下:
代号 | 代表内容 |
---|---|
1 | 用户在shell环境中可以操作的或可执行文件 |
2 | 系统内核可调用的函数与工具等 |
3 | 一些常用的函数(function)与函数库(library),大部分为C的函数库(libc) |
4 | 设备文件的说明,通常在/dev下的文件 |
5 | 配置文件或是某些文件的格式 |
6 | 游戏(games) |
7 | 惯例与协议等,例如Linux文件系统、网络协议、ASCII代码等的说明 |
8 | 系统管理员可用的管理命令 |
9 | 跟内核有关的文件 |
其他命令代号:
代号 | 内容说明 |
---|---|
NAME | 简短的命令、数据名称说明 |
SYNOPSIS | 简短的命令语法(syntax)简介 |
DESCRIPTION | 较为完整的说明,这部分最好仔细看看 |
OPTIONS | 针对SYNOPSIS部分中,有列举的所有可用的选项说明 |
COMMANDS | 当这个程序(软件)在执行的 |
FILES | 这个程序或数据所使用或参考或链接到的某些文件 |
SEE ALSO | 可以参考跟这个命令或数据有相关的其他说明 |
EXAMPLE | 一些可以参考的范例 |
查阅顺序:
man page内部常用的按键:
按键 | 进行工作 |
---|---|
空格键 | 向下翻一页 |
[Page Down] | 向下翻一页 |
[Page Up] | 向上翻一页 |
[Home] | 去到第一页 |
[End] | 去到最后一页 |
/string | 向【下】查找string这个字符串,如果要查找vbird的话,就输入/vbird |
?string | 向【上】查找string这个字符串 |
n,N | 利用/或?来查找字符串时,可以用n来继续下一个查找(不论是/或?),可以利用N来进行【反向】查找(向上查找) |
q | 结束这次的man page |
man -f man:取得更多的与man相关的信息。
man -k man:利用关键词将说明文件里面只要含有man那个字眼就将它取出。
info page:和man page类似,与man page一口气输出一堆信息不同的是,info page则是将文件数据拆成一个一个的段落,每个段落用自己的页面来编写,并且在各个页面中还有类似网页的超链接来跳到各个不同的页面中,每个独立的页面也被称为一个**节点**(node)。所以,你可以将info page想成是命令行模式的网页显示数据。
按键 | 进行工作 |
---|---|
空格键 | 向下翻一页 |
[Page Down] | 向下翻一页 |
[Page Up] | 向上翻一页 |
[Tab] | 在节点之间移动,有节点的地方,通常会以*显示 |
[Enter] | 当光标在节点上面时,按下Enter可以进入该节点 |
b | 移动光标到该info界面当中的第一处 |
e | 移动光标到该info界面当中的最后一个节点一处 |
n | 前往下一个节点处 |
p | 前往上一个节点处 |
u | 向上移动一层 |
s(/) | 在info page当中进行查找 |
h,? | 显示帮助选项 |
q | 结束这次的info page |
打开一个名为text.txt的文件: nano text.txt
其中,那个指数符号(^)代表的是键盘的[Ctrl]按键;
M代表的是键盘的[Alt]按键。
正确的关机命令使用
一般在重新启动时,都会执行如下的命令:
sync; sync; sync; reboot
执行操作
ls -al
或
ll
可以显示文件的文件名和相关属性,如下:
dr-xr-x--- 5 root root 4096 May 29 16.08 .
//[1] [2] [3] [4] [5] [6] [7]
//[权限] [链接] [拥有者] [用户组] [文件容量] [修改日期] [文件名]
详细介绍第一栏[1]的十位字符所代表的含义
第一栏代表这个文件的类型与权限(permission)
第二栏表示有多少文件名链接到此节点(inode)
每个文件都会将它的权限与属性记录到文件系统的inode中,不过,我们使用的目录树却是使用文件名来记录,因此每个文件名就会链接到一个inode,这个属性记录的就是有多少不同的文件名链接到相同的一个inode号码。
第三栏表示这个文件(或目录)的拥有者账号
第四栏表示这个文件的所属用户组
第五栏为这个文件的容量大小,默认单位为Bytes
第六栏为这个文件的创建日期或是最近的修改日期
第七栏为这个文件名
修改所属用户组,chgrp
这个命令是change group的缩写,用以修改一个文件的用户组,不过被修改的组名必须要在/etc/group文件中存在才行,否则会显示错误。
//把a的拥有者修改b
chgrp a b
修改文件拥有者,chown
这个命令是change owner的缩写,用以修改文件拥有者,用户必须是已经存在系统中的账号,也就是在/ect/passwd这个文件中有记录的用户名称才能修改。
//把b的拥有者修改为a
chown a b
复制文件命令,cp
cp操作会复制执行者的属性与权限,但是无法修改
cp 源文件 目标文件
//复制一个与文件a一样属性的文件b
cp a b
修改权限,chmod
**chmod**用于修改文件权限,权限有两种:使用数字或是符号来进行权限的修改。
数字类型修改文件权限
Linux文件的基本权限就有9个,分别是拥有者(owner)、所属群组(group)、其他人(others)三种身份各有自己的读(read)、写(write)、执行(execute)权限三个一组,可以使用数字来代表各个权限,如下:
r:4
w:2
x:1
每种身份各自的三个权限数字是需要累加的,例如当权限是[-rwxrwx—],数字则是:
owner = rwx = 4+2+1 = 7
group = rwx = 4+2+1 = 7
others = --- = 0+0+0 = 0
当修改权限时,若要修改.txt这个文件所有的权限都设置启用([-rwxrwxrwx]),那么就执行:
chmod 777 .txt
符号类型修改文件权限
chmod | u(user) | +(加入) | r | 文件或目录 |
g(group) | -(移除) | w | ||
o(others) | =(设置) | x | ||
a(all) |
按照上一个需求,符号修改的操作方式是:
chmod a = rwx .txt
cat:将一个文件内容读出来的命令
//可以看到文件内容
cat ~/.txt
可分享(shareable) | 不可分享(unshareable) | |
不变(static) | /usr(软件存放处) | /etc(配置文件) |
/opt(第三方辅助软件) | /boot(启动与内核文件) | |
可变动(variable) | /var/mail(用户邮箱) | /var/run(程序相关) |
/var/spool/news(新闻组) | /var/lock(程序相关) |
事实上,FHS针对目录树架构仅定义出三层目录下面应该放置什么数据而已,分别是下面这三个目录的定义:
/(root,根目录):与启动系统有关;
/usr(unix software resource):与软件安装/执行有关;
/var(variable):与系统运行过程有关。
根目录(/)的意义与内容
根目录是整个系统最重要的一个目录,因为不但所有的目录都是由根目录衍生出来,同时根目录也与启动、还原、系统修复等操作有关。
因此,根据FHS标准建议:根目录(/)所在分区应该越小越好,且应用程序所安装的软件最好不要与根目录放在同一个分区,保持根目录越小越好。如此不但性能较佳,根目录所在的文件系统也较不容易发生问题。
目录 | 应放置文件内容 |
第一部分:FHS要求必须要存在的目录 | |
/bin | 系统有很多存放执行文件的目录,但/bin比较特殊。因为/bin放置的是在单人维护模式下还能够被使用的命令。在/bin下面的命令可以被root与一般账号使用,主要有:cat、chmod、chown、date、mv、mkdir、cp、bash等常用的命令。 |
/boot | 这个目录主要是放置启动会使用到的文件,包括Linux内核文件以及启动选项与启动所需配置文件等。Linux内核常用的文件名为:vmlinuz,如果使用的是grub2这个启动引导程序,则还会存在/boot/grub2/这个目录。 |
/dev | 在Linux系统上,任何设备与接口设备都是以文件的形式存在于这个目录当中。你只要通过读写这个目录下面的某个文件,就等于读写某个设备,比较重要的文件有/dev/null/dev/zero、/dev/tty、/dev/loop*、/dev/sd*等。 |
/etc | 系统主要的配置文件几乎都放在这个目录内,例如人员的账号密码文件、各种服务的启动文件等。一般来说,这个目录下的各文件属性是可以让一般用户查看的,但是只有root有权利修改。FHS建议不要放置可执行文件(binary)在这个目录中。比较重要的文件有:/etc/modprobe.d/、/etc/passwd、/etc/fstab、/etc/issue等。另外FHS还规范几个重要的目录最好要存在/etc/目录下: - /etc/cpt(必要):这个目录在放置第三方辅助软件/opt的相关配置文件; - /etc/X11/(建议):与X Window有关的各种配置文件都在这里,尤其是xorg.conf这个X Server的配置文件; - /etc/sgml/(建议):与SGML格式有关的各项配置文件; - /etc/xml/(建议):与XML格式有关的各项配置文件; |
/lib | 系统的函数库非常多,而/lib放置的则是在启动时会用到的函数库,以及在/bin或/sbin下面的命令会调用的函数库而已。什么是函数库?你可以将它想成是外挂,某些命令必须要有这些外挂才能够顺利完成程序的执行之意,另外FSH还要求下面的目录必须要存在: - /lib/modules/:这个目录主要放置可抽换式的内核相关模块(驱动程序)。 |
/media | media是媒体的英文,顾名思义,这个/media下面放置的就是可删除的设备,包括软盘、光盘、DVD等设备都暂时挂载于此。常见的文件名有:/media/floppy、/media/cdrom等。 |
/mnt | 如果你想要暂时挂载某些额外的设备,一般建议你可以放置到这个目录中。在早些时候,这个目录的用途和/media相同。只是有了/media之后,这个目录就暂时用来挂载了。 |
/opt | 这个是给第三方辅助软件放置的目录。什么是第三方辅助软件?举例来说,KDE这个桌面管理系统是一个独立的软件,不过它可以安装到Linux系统中,因此KDE的软件就建议放置到此目录下。另外,如果你想要自行安装额外的软件(非原来的发行版提供),那么也能够将你的软件安装到这里来。不过,以前的Linux系统中,我们还是习惯放置在/usr/local目录下。 |
/run | 早期的FHS规定系统启动后所产生的各项信息应该要放置到/var/run目录下,新版的FHS则规范到/run下面,由于/run可以使用内存来模拟,因此性能上会好很多。 |
/sbin | Linux系统有非常多命令是用来设置系统环境的,这些命令只有root才能够用来设置系统,其他用户最多只能用来查询而已。放在/sbin下面的为启动过程中所需要的,里面包括了启动、修复、还原系统所需要的命令。至于某些服务器软件程序,一般则是放置到/usr/sbin/当中。至于本机自行安装的软件所产生的系统执行文件(system binary),则放置到/usr/local/sbin/当中了。常见的命令包括:fdisk、fsck、ifconfig、mkfs等。 |
/srv | srv可以视为service的缩写,是一些网络服务启动之后,这些服务所需要使用的数据目录,常见的服务例如WWW、FTP等。举例来说。WWW服务器需要的网页数据就可以放置在/srv/www/里面。不过,系统的服务数据如果尚未要提供给因特网任何人浏览的话,默认还是建议放置到/var/lib下面即可。 |
/tmp | 这是让一般用户或是正在执行的程序暂时放置文件的地方。这个目录是任何人都能够存放的,所以你需要定期地清理一下。当然,重要数据不可放置在此目录。因为FHS甚至建议在启动时,应该要将/tmp下的数据都删除。 |
/usr | 第二层FHS设置,后续介绍。 |
/var | 第二层FHS设置,主要为放置变动性的设置,后续介绍。 |
第二部分:FHS建议可以存在的目录 | |
/home | 这是系统默认的用户家目录(home directory)。在你新增应该一般用户账号时,默认的用户家目录都会规范到这里来,比较重要的是家目录有两种代号: - ~:代表目前这个用户的家目录; - ~dmtsai:则代表dmtsai的家目录。 |
/lib | 用来存放与/lib不同的格式的二进制函数库,例如支持64位的/lib64函数库等。 |
/root | 系统管理员(root)的家目录,之所以放在这里,是因为如果进入单人维护模式而仅挂载根目录时,该目录就能够拥有root的家目录,所以我们会希望root的家目录与根目录放置在同一个分区中。 |
Linux下几个也非常重要的目录
目录 | 应放置文件内容 |
/lost+found | 这个目录是使用标准的ext2、ext3、ext4文件系统格式才会产生的一个目录,目的在于当文件系统发生错误时,将一些遗失的片段放置在这个目录下,不过如果使用的是xfs文件系统的话,就不会存在这个目录。 |
/proc | 这个目录本身是一个虚拟文件系统(virtual filesystem),它放置的数据都是在内存中,例如系统内核、进程信息(process)、外接设备的状态及网络状态等。因为这个目录下的数据都是在内存当中,所以本身不占任何硬盘空间。比较重要的文件例如:/proc/cpuinfo\/proc/dma\/proc/interrupts\/proc/ioports\/proc/net/*等。 |
/sys | 这个目录其实跟/proc非常相似,也是一个虚拟的文件系统,主要也是记录内核与系统硬件信息相关的内容。包括目前已加载的内核模块与内核检测到的硬件设备等,这个目录同样不占硬盘容量。 |
/usr的意义与内容
根据FHS的基本定义,/usr里面放置的数据属于可分享与不可变动(shareable,static)。
usr是UNIX Software Resource的缩写,这个目录有点内似于Windows系统的“C:\Windows\(当中的一部分)+C:\Program Files\”这两个目录的综合体。
目录 | 应放置文件内容 |
第一部分:FHS要求必须要存在的目录 | |
/usr/bin/ | 所以一般用户能够使用的命令都放在这里。目前新的CentOS 7已经将全部的用户命令放置于此,而使用链接文件的方式将/bin链接至此。也就是说,/usr/bin与/bin是一模一样的。另外,FHS要求在此目录下不应该有子目录。 |
/usr/lib/ | 基本上,与/lib功能相同,所以/lib就是链接到此目录中。 |
/usr/local/ | 系统管理员在本机安装自己下载的软件(非发行版默认提供者)。建议安装到此目录,这样会比较便于管理。举例来说,你的发行版提供的软件较旧,你想安装较新的软件但又不想删除旧版,此时你可以将新版软件安装于/usr/local/目录下,可与原先的旧版软件有分别。你可以自行到/usr/local去看看,该目录下也是具有bin、etc、include、lib...的子目录。 |
/usr/sbin/ | 非系统正常运行所需要的系统命令,最常见的就是某些网络服务器软件的服务命令(daemon)。不过基本功能与/sbin也差不多,因此目前/sbin就是链接到此目录中的。 |
/usr/share/ | 主要放置只读的数据文件,当然也包括共享文件。、在这个目录下放置的数据几乎是不分硬件架构的可读取的数据,因为几乎都是文本文件。在此目录下常见的还有这些子目录: - /usr/share/man:在线帮助文件; - /usr/share/doc:软件的说明文档; - /usr/share/zoneinfo:与时区有关的时区文件。 |
第二部分:FHS建议可以存在的目录 | |
/usr/games/ | 与游戏比较相关的数据放置处。 |
/usr/include/ | c/c++等程序语言的头文件(header)与包含文件(include)放置处,当我们以Tarball方式(*.tar.gz的方式安装软件)安装某些程序时,会使用到里面的许多文件。 |
/usr/libexec/ | 某些不被一般用户常用的执行文件或脚本(script)等,都会放置在此目录中。例如大部分的X窗口下面的操作命令,很多都是方在此目录下。 |
/usr/lib/ | 与/lib/功能相同,因此目前/lib就是链接到此目录中。 |
/usr/src/ | 一般源代码建议放置到这里,src有source的意思。至于内核源代码则建议放置到/usr/src/Linux/目录下。 |
/var的意义与内容
目录 | 应放置文件内容 |
第一部分:FHS要求必须要存在的目录 | |
/var/cache/ | 应用程序本身运行过程中会产生的一些缓存。 |
/var/lib/ | 程序本身执行的过程中,需要使用到的数据文件放置的目录。在此目录下各自的软件应该要有各自的目录。举例来说,MySQL的数据库放置到/var/lib/mysql/而rpm的数据库则放到/var/lib/rpm中。 |
/var/lock/ | 某些设备或是文件资源一次只能被一个应用程序所使用,如果同时有两个程序使用该设备时,就可能产生一些错误的状况,因此就得要将该设备上锁(lock),以确保该设备只会给单一软件所使用。举例来说,刻录机正在刻录一张光盘,你想一下会不会有两个人同时在使用一个刻录机刻盘?如果两个人台式刻录,那光盘写入的是谁的数据?所以当第一个人在刻录时刻录机就会被上锁,第二个人就得要该设备被解除锁定(就是前一个人用完了)才能够继续使用,目前此目录也已经挪到/run/lock中。 |
/var/log/ | 重要到不行。这是日志文件放置的目录,里面比较重要的文件有/var/log/messages、/var/log/wtmp(记录登录信息)等。 |
/var/mail/ | 放置个人电子邮箱的目录,不过这个目录也被放置到/var/spool/mail/目录中,通常这两个目录是互为链接文件。 |
/var/run/ | 某些程序或是服务启动后,会把它们的PID放置在这个目录下,至于PID的意义我们会在后续章节提到,与/run相同,这个目录链接到/run目录。 |
/var/spool/ | 这个目录通常放置一些队列数据,所谓的队列就是排队等待其他程序使用的数据,这些数据被使用后通常都会被删除。举例来说,系统收到新邮件会放置到/var/spool/mail/中,但用户收下该邮件后该封信原则上就会被删除,邮件如果暂时寄不出去会被放到/var/spool/mqueue/中,等到被送出后就被删除。如果是计划任务数据(crontab),就会被放置到/var/spool/cron/目录中。 |
在Linux下面,所有的文件与目录都是由根目录开始的。那是所有目录与文件的源头,然后在一个一个的分支下来,有点像是树枝状,因此,我们也称这种目录配置方式为:目录树(directory tree),这个目录有什么特殊?它主要的特征有:
目录树的启动点为根目录(/,root);、
每一个目录不止能使用本地分区的文件系统,也可以使用网络上的文件系统。举例来说,可以利用Network File System(NFS)服务器挂载某特定目录等;
每一个文件在此目录树中的文件名(包含完整路径)都是独一无二的。
根据文件名写法的不同,也可将所谓的路径(path)定义为绝对路径(absolute)与相对路径(relative)。这两种文件名/路径的写法依据是这样的:
绝对路径:由根目录(/)开始写起的文件名或目录名称,例如/home/dmtsai/.bashrc;
相对路径:相对于目录路径的文件名写法,例如./home/dmtsai或…/…/home/dmtsai等,反正开头不是/就属于相对路径的写法。
例子,你目前在/home这个目录下,如果想要进入/var/log这个目录时,可以怎么写?
1. cd /var/log(absolute)
2. cd ../var/log(relative)
因为你在/home下面,所以要回到上一层(…/)之后,才能继续往/var来移动。特别注意这两个特殊的目录:
.: 代表当前的目录,也可以使用./来表示;
…: 代表上一层目录,也可以使用…/来表示。
例题
如何先进入/var/spool/mail/目录,再进入到/var/spool/cron/目录中呢?
**答:**由于/var/spool/mail与/var/spool/cron是同样在/var/spool/目录中,因此最简单的命令执行方法为:
1. cd /var/spool/mail
2. cd ../cron
例题
网络文件常常提到类似“./run.sh”之类的数据,这个命令的意义是什么?
**答:由于命令的执行需要变量(bash章节才会提到)的支持,若你的执行支持放置在本目录,并且本目录并非常规的执行文件目录(/bin,/usr/bin等为常规),此时要执行命令就得要严格指定该执行文件。“/”代表“本目录”**的意思,所以“./run.sh”代表“执行本目录下名为run.sh的文件”。
绝对路径:路径的写法“一定由根目录(/)写起”,例如/usr/share/doc。
绝对路径的正确度要比较好。
如果在写程序(shell脚本)来管理系统的条件下,务必使用绝对路径。
相对路径:路径的写法“不是由根目录(/)写起”,例如由/usr/share/doc要到/usr/share/man下面时,可以写成:“cd …/main”。
比较特殊的目录:
几个常见的处理目录的命令:
利用相对路径的写法必须要确认你目前的路径才能正确地去到想要去的目录。
回到上层目录可以用 “cd …”,这个命令太常见,就不阐述了。
选项与参数:
-p : 显示出真正的路径,而非使用链接(link)路径。
在默认的情况下,你所需的目录得一层一层地建立才行。
选项与参数:
-m : 设置文件的权限,直接设置,不使用默认权限(umask)
可以利用-m来强制设置一个新目录相关的权限。比如“mkdir -m 711 test”就是给予test一个drwx–x–x的权限。
-p : 帮助你直接将所需要的目录(包括上层目录)递归创建
执行“mkdir -p /home/bird/test”,系统就会自动帮你依序生成目录。并且,如果该目录本来存在时,系统也不会显示错误信息。不过,不建议常用-p这个选项,因为担心如果打错字,那么目录名称就会变得乱七八糟。
选项与参数:
-p : 连同上层“空的”目录也一起删除
目录需要一层一层删除才行,而且被删除的目录里面必定不能存在其他的目录或文件,这也是所谓的空目录(empty directory)的意思。
如果要将所有目录下的东西都删除?这个时候就必须使用【rm -f test】。不过,还是使用rmdir比较安全。
“为什么我可以在任何地方执行/bin/ls这个命令?”
“这是因为环境变量PATH的帮助所致。”
echo $PATH
(显示)/usr/local/sbin:/usr/local/bin:/bin:/usr/sbin:/usr/bin:/root/bin
echo有“显示,打印”的意思,PATH前面加的 $ 表示后面接的是变量,所以会显示出目前的PATH。
PATH(一定是大写)这个变量的内容是由一堆目录所组成,每个目录中间用冒号(:)来隔开,每个目录有顺序之分。
例题:
假设你是root,如果你将ls由/bin/ls移动成为/root/ls(可用【mv /bin/ls /root】命令完成),然后你自己本身也在/root目录下,请问(1)你能不能直接输入ls来执行?(2)若不能,你该如何执行ls这个命令?(3)若要直接输入ls即可执行,又该如何进行?
答:
由于这个例题的重点是将某个执行文件移动到非正规目录去,所以我们先要进行下面的操作才行(务必先使用su - 切换成为root身份):
mv /bin/ls /root
(mv为移动,可将文件在不同的目录间进行移动操作)
(1)接下来不论你在哪个目录下面输入任何与ls相关的命令,都没有办法顺利地执行ls。也就是说,你不能直接输入ls来执行,因为/root这个目录并不在PATH指定的目录中,所以,即便你在/root目录下,也不能够查找到ls这个命令。
(2)因为这个ls确实存在与/root下面,并不是被删除了。所以我们可以通过使用绝对路径或是相对路径直接指定这个执行文件,下面的两个方法都能够执行ls这个命令:
/root/ls (直接用绝对路径指定改文件名)
./ls (因为在/root目录下,就用./ls来指定)
(3)如果想要让root在任何目录均可执行/root下面的ls,那么就将/root加入PATH当中即可。加入的方法很简单,就像下面这样:
PATH = “${PATH}:/root”
上面这个做法就能够将/root加入到执行文件查找路径PATH中了。**另外,除了 P A T H 之 外 , 如 果 想 要 更 明 确 地 定 义 出 变 量 的 名 称 , 可 以 使 用 大 括 号 PATH之外,如果想要更明确地定义出变量的名称,可以使用大括号 PATH之外,如果想要更明确地定义出变量的名称,可以使用大括号{PATH}来处理变量的调用。**如果确定这个例题进行的没有问题,请将ls移回/bin下面,不然系统会挂。
mv /root/ls /bin
某些情况下,即便你已经将ls移回了/bin目录,不过系统还是会告诉你无法处理/root/ls。很可能是因为指向系统参数被缓存的关系。不要紧张,只要注销(exit)再登录(su -)就可以继续快乐地使用ls命令了。
总结:
不同的身份用户默认的PATH不同,默认能够随便执行的命令也不同(如root与dmtsai)
PATH是可以修改的
使用绝对路径或相对路径直接指定某个命令的文件名来执行,会比查找PATH来的正确
命令应该要放置到正确的目录下,执行才会比较方便
本目录(.)最好不要放到PATH当中
ls [-aAdfFhilnrRST] 文件名或文件目录
ls [--color={never,auto,always}] 文件名或文件目录
ls [--full-time] 文件名或文件目录
选项与参数:
-a : 全部的文件,连同隐藏文件(开头为.的文件)一起列出来;
-A : 全部的文件,连同隐藏文件,但不包括.与…这两个目录;
-d : 仅列出目录本身,而不是列出目录内的文件数据;
-f : 直接列出结果,而不进行排序(ls默认会以文件名排序);
-F : 根据文件、目录等信息,给予附加数据结构,例如:
-h : 将文件容量以人类较易读的方式(例如GB、KB等)列出来;
-i : 列出inode号码,inode的意义下一章将会介绍;
-l : 详细信息显示,包含文件的属性与权限等数据;(很多版本简化为ll)
-n : 列出UID与GID而非使用者与用户组的名称(UID与GID会在账号管理提到);
-r : 将排序结果反向输出,例如:原本文件名由小到大,反向则为由大到小;
-R : 连同子目录内容一起列出来,等于该目录下的所有文件都会显示出来;
-S : 以文件容量大小排序,而不是用文件名排序;
-t : 依时间排序,而不是用文件名。
–color=never : 不要依据文件特性给予颜色显示;
–color=always : 显示颜色;
–color=auto : 让系统自行依据设置来判断是否给予颜色。
–full-time : 以完整时间模式(包括年、月、日、时、分)输出;
–time={atime,ctime} : 输出access时间或改变权限属性时间(ctime),而非内容修改时间(modification time)。
当只执行ls时,默认显示为:非隐藏文件的文件名、以文件名进行排序及文件名代表的颜色显示。
cp [-adfilprsu] 源文件(source) 目标文件(destination)
cp [options] source1 source2 ... directory
选项与参数:
-a : 相当于-dr --preserve=all的意思,至于dr请参考下列说明;(将文件的所有特性都复制过来)
-d : 若源文件为链接文件的属性(link file),则复制链接文件属性而非文件本身;
-f : 为强调(force)的意思,若目标文件已经存在且无法开启,则删除后再尝试一次;
-i : 若目标文件(destination)已经存在时,在覆盖时会先询问操作的进行;
-l : 进行硬链接(hard link)的链接文件建立,而非复制文件本身;
-p : 连同文件的属性(权限、用户、时间)一起复制过去,而非使用默认属性;
-i : 递归复制,用于目录的复制操作;
-s : 复制成为符号链接文件(symbolic link),亦即“快捷方式”文件;
-u : destination比source旧才更新destination,或destination不存在的情况下才复制;
–preserve=all : 除了-p的权限相关参数外,还加入SELinux的属性,links、xattr等也复制。
注意:
如果源文件有两个以上,则最后一个目标文件一定要是“目录”才行。
想要复制到目前的目录,最后得加上“.”才行。
cp /var/log/wtmp .
复制(cp)这个命令是非常重要的,不同身份者执行这个命令会有不同的结果产生,尤其是那个-a、-p的选项,对于不同的身份来说,差异则非常大。
如果没有加上任何选项时,cp复制的是原始文件,而非链接文件的属性。若要复制链接文件的属性,就要使用-d。
rm [-fir] 文件或目录
选项与参数:
-f : 就是force的意思,忽略不存在的文件,不会出现警告信息;
-i : 交互模式,在删除前会询问使用者是否操作;
-r : 递归删除,最常用于目录的删除,这是非常危险的选项。
注意:
通过通配符(*)的帮忙,将/temp下面开头为bashrc的文件名通通删除:
rm -i bashrc*
注意那个星号*,代表0到无穷多个任意字符,很好用的东西。
一个问题:
\rm -r /temp/etc
在命令前加反斜线(\),可以忽略掉alias的指定选项。
mv [-fiu] source destination
mv [options] source1 source2 .. directory
选项与参数:
-f : force强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
-i : 若目标文件(destination)已经存在时,就会询问是否覆盖;
-u : 若目标文件已经存在时,且source比较新,才会更新(update)。
重命名某个文件:
mv mytest mytest2
basename /etc/sysconfig/network
(结果)network //取得最后的文件名
dirname /etc/sysconfig/network
(结果)/etc/sysconfig //取得的变成了目录名
cat由第一行开始显示文件内容;
tac从最后一行开始显示,可以看出tac是cat的倒着写;
nl显示的时候,同时输出行号;
more一页一页地显示文件内容;
less与more类似,但是比more更好的是,它可以往前翻页;
head只看前面几行;
tall只看后面几行;
od以二进制的方式读取文件内容。
直接查看一个文件的内容可以使用cat/tac/nl这几个命令。
cat [-AbEnTv]
选项与参数:
- -A : 相当于-vET的整合选项,可列出一些特殊字符而不是空白而已(完整显示信息);
- -b : 列出行号,仅针对非空白行做行号显示,空白行不标行号;
- -E : 将结尾的换行符$显示出来;
- **-n : 打印出行号,连同空白行也会有行号,与-b的选项不同;**
- -T : 将[tab]按键以^I显示出来;
- -v : 列出一些看不出来的特殊字符。
tac /etc/issue
tac刚好是cat反写过来,所以它的功能就跟cat相反,cat是由第一行到最后一行连续显示在屏幕上,而tac则是由最后一行到第一行反向在屏幕上显示出来。
nl [-bnw] 文件
选项与参数:
- -b : 指定行号指定的方式,主要有两种:
-b a : 表示不论是否为空行,也同样列出行号(类似cat -n);
-b t : 如果有空行,空的那一行不要列出行号(默认值)。
- -n : 列出行号表示的方式,主要有三种:
-n ln : 行号在屏幕的最左方显示;
-n rn : 行号在自己栏位的最右方显示,且不加0;
-n rz : 行号在自己栏位的最右方显示,且加0。
- -w : 行号栏位的占用的字符数。
nl可以将输出的文件内容自动地加上行号,其默认的结果与cat -n有点不太一样,nl可以将行号做比较多的显示设计,包括位数是否自动补充0等的功能。
例:
nl -b a -n rz -w 3 、/etc/issue
(结果)001 \S
(结果)002 Kernel \r on an \m
(结果)003
行号变成仅有的3位数
more /etc/man_db.conf
重点在最后一行,最后一行会显示出目前显示的百分比,而且还可以在最后一行输入一些有用的命令。
- 空格键(space) : 代表向下翻一页;
- Enter : 代表向下翻一行;
- /字符串 : 代表在这个显示的内容当中,向下查找字符串这个关键词;
- :f : 立刻显示出文件名以及目前显示的行数;
- q : 代表立刻立刻more,不再显示该文件内容;
- b或[ctrl]-b : 代表往回翻页,不过这操作只对文件有用,对管道无效。
less /etc/man_db.conf
less的用法比起more又更加有弹性,在more的时候,我们并没有办法向前面翻,只能往后翻。
- 空格键(space) : 向下翻动一页;
- [pagedown] : 向下翻动一页;
- [pageup] : 向上翻动一页;
- /字符串 : 向下查找字符串的功能;
- ?字符串 : 向上查找字符串的功能;
- n : 重复前一个查找(与/或?有关);
- N : 反向的重复前一个查找(与/或?有关);
- g : 前进到这个数据的第一行;
- G : 前进到这个数据的最后一行去(注意大小写);
- q : 代表立刻立刻more,不再显示该文件内容。
head [-n number] 文件
选项与参数:
-n : 后面接数字,代表显示几行的意思。
系统默认的情况中,显示前面十行,若要显示前20行,就得要这样。
head -n 20 /etc/man_db.conf
如果后面100行的数据都不打印,只打印/etc/man_db.conf的前面几行:
head -n -100 /etc/man_db.conf
//-n -100 表示列出前面所有行数,但不包括后面100行
tail [-n number] 文件
选项与参数:
-n : 后面接数字,代表显示几行的意思;
-f : 表示持续刷新显示后面所接文件中的内容,要等到按下[ctrl]-c才会结束。
系统默认的情况中,显示后面十行,若要显示最后20行,就得要这样。
tail -n 20 /etc/man_db.conf
如果不知道/etc/man_db.conf有几行,却只想列出100行以后的数据:
tail -n +100 /etc/man_db.conf
//-n +100 表示该文件以后100行都会被列出来
例:
假如想要显示/etc/man_db.conf的第11行到第20行?
答:
先取前二十行,再取后十行,所以就是:
head -n 20 /etc/man_db.conf | tail -n 10
可以将数据文件(data file)或是二进制文件(binary file)的内容数据读出来。
od [-t TYPE] 文件
选项与参数:
-t : 后面可以接各种【类型(TYPE)】的输出,例如:
a : 利用默认的字符来输出;
c : 使用ASCII字符来输出;
d[size] : 利用十进制(decimal)来输出数据,每个整数占用size Bytes;
f[size] : 利用浮点数值(floatingl)来输出数据,每个整数占用size Bytes;
o[size] : 利用八进制(octal)来输出数据,每个整数占用size Bytes;
x[size] : 利用十六进制(hexadecimal)来输出数据,每个整数占用size Bytes;
例:
//请将/etc/issue这个文件的内容以八进制列出储存值与ASCII的对照表
od -t oCc /etc/issue
----------借楼----------
详细参见https://blog.csdn.net/qq_31246691/article/details/77282461
其实 od -t oCc /etc/issue 等价于 od -t oC -t c /etc/issue
C代表的是char的size,S代表short,I代表int,L代表long int;
F代表float,D代表double,L此时代表long double。
当执行od -t oc /etc/issue 时:
会发现上下无法对应上,这是因为,od命令默认是按Int读取数字的,而Int是按4字节分割的,一行只有16字节,当然只能分为四段,从而无法与下面对齐(下面是char,按照1个字节截取)。所以便有了oC,来使得数字也是按照char来截取,便可以与下面对齐。如下为 od -t oCc /etc/issue 执行结果:
修改时间(modification time,mtime):
当该文件的【内容数据】变更时,就会更新这个时间,内容数据指的是文件的内容,而不是文件的属性或权限。
状态时间(status time,ctime):
当该文件的【状态(status)】改变时,就会更新这个时间,举例来说,像是权限与属性被更改了,都会更新这个时间。
读取时间(access time,atime):
当【该文件的内容被读取】时,就会更新这个读取时间(access),举例来说,我们使用 cat 去读取/etc/man_db.conf,就会更新该文件的atime。
touch [-acdmt]
选项与参数:
-a : 仅自定义access time;
-c : 仅修改文件的时间,若该文件不存在则不新建新文件;
-d : 后面可以接欲自定义的日期而不用目前的日期,也可以使用–date=“日期或时间”;
-m : 仅修改mtime;
-t : 后面可以接欲自定义的时间而不用目前的时间,格式为[YYYYMMDDhhmm]。
例:
//新建一个空文件
touch testtouch
//修改bashrc文件,将日期调整为两天前
touch -d “2 days ago” bashrc
//修改bashrc文件,将日期调整为2014/06/15 2:02
touch -t 201406150202 bashrc
通过touch这个命令,可以轻易地自定义文件的日期与时间,并且也可以建立一个空文件。不过,要注意的是,即使我们复制一个文件时,复制所有的属性,但也没有办法复制ctime这个属性。ctime可以记录这个文件最近的状态(status)被改变的时间。
umask就是指定目前用户在建立文件或目录时候的权限默认值。
umask
(结果)0022
umask -S
u=rwx,g=rx。o=rx
查看的方式有两种,一种是直接输入umask,就可以看到数字类型的权限设置值,一种则是加上-S(Symbolic)这个选项,就会以符号类型的方式来显示出权限了。
注意:umask的数字指的是**该默认值需要减掉的权限**,第一组数字是特殊权限用的。
举例来说:因为umask默认是022,所以user并没有被拿掉任何权限,不过group和others的权限被拿掉了2(也就是w的权限),那么当用户:
建立文件时:(-rw-rw-rw-) - (-----w–w-) ==> -rw-r–r–
建立目录时:(drwxrwxrwx) - (d----w–w-) ==> drwxr-xr-x
root的umask默认值是022,这是基于安全的考虑,至于一般身份用户,通常它们的umask为002,即保留同用户组的写入权力,如果想更改umask的默认值,可以这样修改:
umask 002
强调一点,chattr命令只能在ext2、ext3、ext4的Linux传统文件系统上面完整生效。
chatter [+-=][ASacdistu]
选项与参数:
+ : 增加某一个特殊参数,其他原本存在的参数则不动;
- : 删除某一个特殊参数,其他原本存在的参数则不动;
= : 直接设置参数,且仅保留后面接的参数;
A : 当设置了A这个属性时,若你在存取此文件(或目录)时,它的存取时间atime将不会被修改,可避免I/O较慢的机器过度的读写磁盘。(目前建议使用文件系统挂载参数处理这个项目);
S : 一般文件是非同步写入磁盘的,如果加上S这个属性时,当你进行任何文件的修改,这个修改会【同步】写入磁盘中。
a : 当设置a之后,这个文件将只能增加数据,而不能删除也不能修改数据,只有root才能设置这个属性;
c : 这个属性设置之后,将会自动的将此文件【压缩】,在读取的时候将会自动解压缩,但是在存储的时候,将会先进行压缩后再存储;
d : 当dump程序被执行的时候,设置d属性将可使该文件(或目录)不会被dump备份;
i : 这个i就很厉害了,它可以让文件【不能被删除、改名、设置链接也无法写入或新增数据。】对于系统安全性有相当大的助益,只有root能设置此属性;
s : 当文件设置了s属性时,如该文件被删除,它将会被完全的从硬盘中删除,所以如果误删,完全没法恢复;
u : 与s相反的,当使用u来配置文件时,如果该文件被删除了,则数据内容其实还存在磁盘中,可以使用来恢复该文件。
注意1:属性设置常见的是a与i的设置值,而且很多设置值必须要是root才能设置;
注意2:xfs文件系统仅支持AadiS而已。
lsattr [-adR] 文件或目录
选项与参数:
-a : 将隐藏文件的属性也显示出来;
-d : 如果接的是目录,仅列出目录本身的属性而非目录内的文件名;
-R : 连同子目录的数据也一并列出来。
当s这个标志出现在文件拥有者的x权限上时,此时就被称为Set UID,简称SUID的特殊权限。
- SUID权限仅对于二进制程序(binary program)有效;
- 执行者对于该程序需要具有x的可执行权限;
- 本权限仅在执行该程序的过程中有效(run-time);
- 执行者将具有该程序拥有者(owner)的权限。
SUID仅可用在二进制程序上,不能够用在shell脚本上面。
当s标志在文件拥有者的x项为SUID,那s在用户组的x则称为Set GID(SGID)。与SUID不同的是,SGID可以针对文件或目录来设置。
如果对于文件来说,SGID有如下功能:
- SGID对二进制程序有用;
- 程序执行者对于该程序来说,需具备x的权限;
- 执行者在执行的过程中将会获得该程序用户组的支持。
如果对于目录来说,SGID有如下功能:
- 用户若对于此目录具有r与x的权限时,该用户能够进入此目录;
- 用户在此目录下的有效目录组(effective group)将会变成该目录的用户组;
- 用途:若用户在此目录下具有w的权限(可以新建文件),则用户所建立的新文件,该文件的用户组与此目录的用户组相同。
这个Sticky Bit(SBIT)目前只针对目录有效,SBIT对目录的作用是:
- 当用户对于此目录具有w、x权限,即具有写入的权限;
- 当用户在该目录下建立文件或目录时,仅有自己与root才有权力删除该文件。
换句话说,当甲这个用户对于A目录具有用户组或其他人的身份,并且拥有该目录w的权限,这表示甲用户对该目录内任何人建立的目录或文件均可进行删除、更名、移动等操作。不过,如果将A的目录加上了SBIT的权限选项时,则甲只能够针对自己建立的文件或目录进行删除、更名、移动等操作,而无法删除它人的文件。
SUID/SGID/SBIT权限设置
4为SUID
2为SGID
1为SBIT
假设要将一个文件权限改成【-rwsr-xr-x】时,由于s在用户权限中,所以是SUID,因此,在原来的755之前还要加上4,也就是【chmod 4755 filename】来设置。
**注意:**若x位为空,此时S与T就代表空的x命令。
简单地先判断文件的格式是什么
//file 文件
file ~/.bashrc
这个命令是根据【PATH】这个环境变量所规范的路径,去查找执行文件的文件名。
which [-a] command
选项与参数:
-a : 将所有由PATH目录中可以找到的命令均列出,而不止第一个被找到的命令名称。
一般我们都是先使用whereis或是locate来检查,如果真的找不到了,才以find来查找。因为whereis只找系统中某些特定目录下面的文件而已,locate则是利用数据库来查找文件名,当然两者就相当的快速,并没有实际查找硬盘内的文件系统状态,比较省时间。
whereis [-bmsu] 文件或目录名
选项与参数:
-l : 可以列出whereis会去查询的几个主要目录;
-b : 只找binary(二进制)格式的文件;
-m : 只找在说明文件manual路径下的文件;
-s : 只找source源文件;
-u : 查找不在上述三个项目当中的其他特殊文件。
locate/updatedb
updatedb:根据/etc/updatedb.conf的设置去查找系统硬盘内的文件,并更新/var/lib/mlocate;
locate:根据/var/lib/mlocate内的数据记录,找出用户所输入关键词的文件名。
locate [-ir] keyword
选项与参数:
-i : 忽略大小写的差异;
-c : 不输出文件名,仅计算找到的文件数量;
-l : 仅输出几行的意思;
-S : 输出locate所使用的数据库文件的相关信息,包括该数据库记录的文件/目录数量等;
-r : 后面可接正则表达式的显示方式。
find [PATH] [option] [action]
选项与参数:
1.与时间有关的选项:共有-atime、-ctime与-mtime,以-mtime说明。
-mtime n : n为数字,意义为在n天之前的【一天之内】被修改过内容的文件;
-mtime +n : 列出在n天之前(不含n天本身)被修改过内容的文件;
-mtime -n : 列出在n天之内(含n天本身)被修改过内容的文件;
-newer file: file为一个存在的文件,列出比file还要新的文件。
例子:
//将过去系统上面24小时内有修改过内容(mtime)的文件列出。
find / -mtime 0
//0代表目前的时间,所以,从现在开始到24小时前。
//寻找/etc下面的文件,如果文件日期比/etc/passwd新就列出。
find /etc -newer /etc/passwd
2.与使用者或用户组名称有关的参数:
-uid n : n为数字,这个数字是使用者的账号ID,亦即UID,这个UID是记录在/etc/passwd里面;
-gid n : n为数字,这个数字是用户组名称的ID,亦即GID,这个GID是记录在/etc/group;
-user name : name为使用者账号名称,例如dmtsai;
-group name : name为用户组名称,例如users;
-nouser : 查找文件的拥有者不在/etc/passwd中;
-nogroup : 查找文件的拥护用户组不存在于/etc/group的文件。当你自行安装软件时,很可能该软件的属性当中并没有文件拥有者,这是可能的,这个时候,就可以使用-nouser或-nogroup查找。
3.与文件权限及名称有关的参数:
-name filename : 查找文件名称为filename的文件;
-size [+-]SIZE : 查找比SIZE还要大(+)或小(-)的文件,这个SIZE的规格有:
c : 代表Bytes, k : 代表1024Bytes。所以,要找比50kB还要大的文件,就是【-size+50k】
-type TYPE : 查找文件的类型为TYPE的,类型主要有:一般正规文件(f),设备文件(b,c),目录(d),链接文件(l),socket(s),及FIFO(p)等属性。
-perm mode : 查找文件权限【刚好等于】mode的文件,这个mode为类似chmod的属性值;
-perm -mode : 查找文件权限【必须要全部囊括mode的权限】的文件;
-perm/mode : 查找文件权限【包含任一mode的权限】的文件,这个mode为类似chmod的属性值。
4.额外可进行的操作:
-exec command : command为其他命令,-exec后面可再接额外的命令来处理查找到的结果。
-print : 将结果打印到屏幕上,这个操作是默认操作。
例子:
find /usr/bin /usr/sbin -perm /7000 -exec ls -l () \;
//注意到,那个-exec后面的ls -l就是额外的命令,命令不支持命令别名(-ll)
其中:
- {}代表的是由find找到的内容,结果会存放在{}中;
- -exec一直到\;是关键词,代表find额外操作的开始(-exec)到结束(\;),在这中间的就是find命令内的额外操作。在本例中就是【ls -l{}】;
- 因为【;】在bash环境下是有特殊意义的,因此利用反斜杠来转义。
#柒、第七章-Linux磁盘与文件系统管理
磁盘分区表主要有两种格式,一种是限制较多的MBR分区表,一种是较新且限制较少的GPT分区表:
MBR分区表中,第一个扇区最重要,里面有:主引导记录(Master boot record,MBR)及分区表(partition table),其中MBR占用446B,而分区表则占用64B;
GPT分区表除了分区数量扩充较多之外,支持磁盘容量也可以超过2TB。
磁盘文件名:
/dev/sd[a-p][1-128] : 为物理磁盘的文件名;
/dev/vd[a-d][1-128] : 为虚拟磁盘的文件名。
Linux的正统文件系统是ext2(Linux second Extended file system,ext2fs)。
通常我们称呼一个可被挂载的数据为一个文件系统而不是一个分区。
文件系统通常会将这两部分的数据分别存放在不同的区块,权限与属性放置到inode中,至于实际数据则放置到数据区块中。另外,还有一个超级区块(superblock)会记录整个文件系统的整体信息,包括inode与数据区块的总量、使用量、剩余量等。
超级区块:记录此文件系统的整体信息,包括inode与数据区块的总量、使用量、剩余量,以及文件系统的格式与相关信息等;
inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的区块号码;
数据区块:实际记录文件的内容,若文件太大时,会占用多个区块。
文件系统一开始就将inode与数据区块规划好了,除非重新格式化(或利用resize2fs等命令修改其大小),否则inode与数据区块固定后就不再变动。
文件系统最前面有一个启动扇区(boot sector),这个启动扇区可以安装启动引导程序。
每一个区块群组(block group)的六个主要内容如下:
数据区块是用来放置文件数据的地方,在ext2文件系统中所支持的区块大小有1K,2K及4K三种。在格式化时区块的大小就固定了,且每个区块都有编号,以方便inode的记录。
Block大小 | 1KB | 2KB | 4KB |
最大单一文件限制 | 16GB | 256GB | 2TB |
最大文件系统总容量 | 2TB | 8TB | 16TB |
ext2文件系统的区块基本限值如下:
- 原则上,区块的大小与数量在格式化完就不能够再修改(除非重新格式化);
- 每个区块内最多只能够放置一个文件的数据;
- 承上,如果文件大于区块的大小,则一个文件会占用多个区块数量;
- 承上,若文件小于区块,则该区块的剩余容量就不能够再被使用了(磁盘空间会浪费)。
inode记录的数据至少有下面这些:
- 该文件的读写属性(read、write、excute);
- 该文件的拥有者与用户组(owner、group);
- 该文件的大小;
- 该文件建立或状态改变的时间(ctime);
- 最近一次的读取时间(atime);
- 最近修改时间(mtime);
- 定义文件特性的标识(flag),如SetUID;
- 该文件真正内容的指向(pointer)。
inode的特色:
- 每个inode大小均固定为128B(新的ext4与xfs可设置256B);
- 每个文件都仅会占用一个inode而已;
- 承上,因此文件系统能够建立的文件数量与inode的数量有关;
- 系统读取文件时需要先找到inode,并分析inode所记录的权限与用户是否符合,若符合才能够读取区块的内容。
inode记录区块号码的区域定义为12个直接、一个间接、一个双间接与一个三间接记录区。
inode本身(128B),里面有12个直接指向区块号码的对照,这12条记录就能够直接取得区块号码。间接就是再拿一个区块来当做记录区块号码的记录区,如果文件太大,就会使用间接的区块来记录编号。
- 12个直接指向:12×1K=12K;
由于是直接指向,所以总共可记录12条记录
- 间接:256×1K=256K;
每条区块号码的记录会使用4B,因此1K的大小那个记录256条记录
- 双间接:256×256×1K=256^2^K
第一层区块会指定256个第二层,每个第二层可以指定256个号码
- 三间接:256×256×256×1K=256^3^K
第一层区块会指定256个第二层,每个第二层可以指定256个第三层,每个第二层可以指定256个号码
- 总额:将直接、间接、双间接、三间接相加,得到12+256+256×256+256×256×256(K)=16G
超级区块是记录整个文件系统相关信息的地方,没有超级区块,就没有这个文件系统,它记录的信息主要有:
- 数据区块与inode的总量;
- 未使用与已使用的inode与数据区块、数量;
- 数据区块与inode的大小(block为1、2、3K,inode为128B或256B);
- 文件系统的挂载时间、最近一次写入数据的时间、最近一次检验磁盘(fsck)的时间等文件系统的相关信息;
- 一个有效位数值,若此文件系统已被挂载,则有效位为0,若未被挂载,则有效位为1.
这个区段可以描述为每个区块群组的开始于结束的区块,以及说明每个区块(超级区块、对照表、inode对照表、数据区块)分别介于哪一区块之间,这部分也能够用dumpe2fs来观察。
从区块对照表当中可以知道哪些区块是空的,因此我们的系统就能够很快速地找到可使用的空间来处理文件。
这个其实与区块对照表的功能类似,只是区块对照表记录的是使用与未使用的区块号码,inode对照表则是记录使用与未使用的inode号码。
dumpe2fs [-bh] 设备文件名
选项与参数:
-b : 列出保留为坏道的部分;
-h : 仅列出superblock的数据,不会列出其他的区段内容
当我们在Linux下的文件系统建立一个目录时,文件系统会分配一个inode与至少一块区块给该目录。其中,inode记录该目录的相关权限与属性,并可记录分配到的那块区块号码,而区块则是记录在这个目录下的文件名与该文件名占用的inode号码数据。
当我们在Linux下的ext2建立一个一般文件时,ext2会分配一个inode与相对于该文件大小的区块数量给该文件。
当我们要读取某个文件时,就务必会经过目录的inode与区块,然后才能够找到那个待读取文件的inode号码,最终才会读取到该文件的区块中的数据。
由于目录树是由根目录开始读起,因此系统通过挂载的信息可以找到挂载点的inode号码,此时就能够得到根目录的inode内容,并依据该inode读取根目录的区块内的文件名数据,再一层一层的往下读到正确的文件名。
磁盘分区的规划并不是越大越好,而是要针对主机的用途来进行规划才行。
假设我们想要新增一个文件,此时文件系统的操作是:
一般来说,我们将inode对照表与数据区块称为数据存放区域,至于其他例如超级区块、区块对照表与inode对照表等区段就被称为元数据(metadata),因为超级区块、inode对照表及区块对照表的数据是经常变动的,每次新增、删除、编辑时都可能会影响到这三个部分的数据,因此才被称为**元数据**。
文件在写入文件系统时,因为某些原因导致系统中断,所以写入的数据仅有inode对照表及数据区块而已,最后一个同步更新元数据的步骤并没有完成,此时就会发生元数据的内容与实际数据存放区产生不一致(Inconsistent)的情况。
简化一致性检查的步骤如下:
1. 预备:当系统要写入一个文件时,会先在日志记录区块中记录某个文件准备要写入的信息;
2. 实际写入:开始写入文件的权限与数据;开始更新metadata的数据;
3. 结束:完成数据与metadata的更新后,在日志记录区块当中完成该文件的记录。
当系统加载一个文件到内存后,如果该文件没有被修改过,则在内存区段的文件数据会被设置为【干净(clean)】。但如果内存中的文件数据被更改过了,此时该内存中的数据会被设置为【脏的(Dirty)】,此时所有的操作都还在内存中执行,并没有写入到磁盘中。
Linux系统上面的文件系统与内存有非常大的关系:
- 系统会将常用的文件数据放置到内存的缓存区,以加速文件系统的读写操作;
- 承上,因此Linux的物理内存最后都会被用光,这是正常的情况,可加速系统性能;
- 你可以手动使用sync来强制内存中设置为Dirty的文件回写到磁盘中;
- 若正常关机时,关机命令会主动调用sync来将内存的数据回写入磁盘内;
- 但若不正常关机,由于数据尚未回写到磁盘内,因此重新启动后可能会花很多时候在进行磁盘校验,甚至可能导致文件系统的损坏(非磁盘损坏)。
每个文件系统都有独立的inode、区块、超级区块等信息,这个文件系统要能够链接到目录树才能被我们使用。将文件系统与目录树结合的操作我们称为【挂载】。挂载点一定是目录,该目录为进入该文件系统的入口。
同一个文件系统的某个inode只会对应到一个文件内容而已(因为一个文件占用一个inode),因此我们可以通过判断inode号码来确认不同文件名是否为相同的文件。
所以Linux系统都是通过一个名为Virtual Filesystem Switch的内核功能去读取文件系统。也就是说,整个Linux识别的文件系统其实都是VFS在进行管理,我们用户并不需要知道每个硬盘分区上面的文件系统是什么,VFS会主动帮我们做好读取的操作。
ext系统当前比较伤脑筋的地方就是:支持度最广,但格式化超慢
XFS文件系统的配置
xfs文件系统在数据的分布上,主要规划为三个部分,一个数据区(data section)、一个文件系统活动登录区(log section)以及一个实时运行区(realtime section),这三个区域的数据内容如下:
- 数据区(data section)
基本上,数据区就跟我们之前谈到的ext系列一样,包括inode、数据区块、超级区块等数据都放置在这个区块。这个数据区与ext系列的区块群组类似,也是分为多个存储区群组(allocation groups)来分别放置文件系统所需要的数据(存储区群组和ext系列的区块群组类似(block groups))。
每个存储区群组都包含了:
(1)整个文件系统的超级区块;
(2)剩余空间的管理机制;
(3)inode的分配与追踪。
此外,inode与区块都是系统需要用到时才动态配置产生,所以格式化操作超级快。
另外,与ext系列不同的是,xfs的区块与inode有多种不同的容量可供设置,区块容量可在512B~64KB调整,不过,Linux的环境下,由于存储控制的关系(页面文件pagesize的容量之故),因此最高可以使用的区块大小为4K而已。
- 文件系统活动登录区(log section)
在登录区这个区域主要被用来记录文件系统的变化,其实有点像是日志区。文件的变化会在这里记录下来,直到该变化完整地写入到数据区后,该条记录才会被结束。
- 实时运行区(realtime section)
当有文件要被建立时,xfs会在这个区段里面找一个到数个的extent区块,将文件放置在这个区块内,等到分配完毕后,再写入到data section的inode与区块中。这个extent区块的大小要在格式化的时候就先指定,最小值是4K最大可到1G。一般非磁盘阵列的磁盘默认为64K容量,而具有类似磁盘阵列的stripe情况下,则建议将extent设置为与stripe一样大,这个extent最好不要乱动,因为可能会影响到物理磁盘的性能。
xfs info 挂载点|设备文件名
df [-ahikHTm] [文件或目录名]
选项与参数:
-a : 列出所有的文件系统,包括系统的特有的/proc等文件系统;
-k : 以KBytes的容量显示各文件系统;
-m : 以MBytes的容量显示各文件系统;
**-h : 以人们较易阅读的GBytes、MBytes、KBytes等格式自行显示;**
-H : 以M=1000K替换M=1024K的进位方式;
-T : 连同该硬盘分区的文件系统名称(例如xfs)也列出;
**-i : 不用磁盘容量,而以inode的数量来显示。**
由于df主要读取的数据几乎都是针对一整个文件系统,因此读取的范围主要是在超级区块内的信息,所以这个命令显示结果的速度非常快。在显示的结果中你需要特别留意的是根目录(/)的剩余容量。因为我们所有的数据都是由根目录衍生出来的。
du [-ahskm] [文件或目录名]
选项与参数:
-a : 列出所有的文件与目录容量,因为默认仅统计目录下面的文件量;
-h : 以人们较易读的容量格式(G/M)显示;
**-s : 仅列出总量,而不列出每个各别的目录占用容量;**
-S : 不包括子目录下的总计,与-s有点差别;
-k : 以KBytes的容量显示各文件系统;
-m : 以MBytes的容量显示各文件系统。
与df不一样的是,du这个命令其实会直接到文件系统内去查找所有的文件数据。
在Linux下面的链接文件有两种,一种是类似Windows的快捷方式功能的文件,可以让你快速地链接到目标文件(或目录);另一种则是通过文件系统的inode链接来产生新文件名,而不是产生新文件,这种称为**硬链接**(hard link)。
硬链接只是在某个目录下新增一条文件名链接到某inode号码的关联记录而已。
如果你将任何一个文件名删除,其实inode与区块都还是存在。
但是硬链接是有限制的:
- 不能跨文件系统
- 不能链接目录
如果使用硬链接到目录时,链接的数据需要连同被链接目录下面的所有数据都建立链接。
符号链接就是建立一个独立的文件,而这个文件会让数据的读取指向它链接的那个文件的文件名。
当源文件被删除之后,符号链接的文件会【打不开了】,会一直说【无法打开某文件】,实际上就是找不到原始文件名而已。
链接文件的重要内容就是它会写入目标文件的文件名。如果目标文件被删除了,那么整个环节就会无法继续进行下去,所以就会发生无法通过链接文件读取的问题。
整个符号链接与Windows的快捷方式可以给它划上等号,有符号链接所建立的文件为一个独立的新的文件,所以会占用inode与区块。
要制作链接文件就必须要使用ln这个命令:
ln [-sf] 源文件 目标文件
选项与参数:
-s : 如果不加任何参数就进行链接,那就是硬链接,至于-s就是符号链接;
-f : 如果目标文件存在时吗,就主动的将目标文件直接删除后再建立。
当我们建立一个新的目录时,【新的目录的链接数为2,而上层目录的链接数则会增加1】。
如果我们想要在系统里面新增一块磁盘时,应该有哪些操作需要做:
lsblk可以看成【list block device】的缩写,就是列出所有存储设备的意思。
lsblk [-dfimpt] [device]
选项与参数:
-d : 仅列出磁盘本身,并不会列出该磁盘的分区数据;
-f : 同时列出该磁盘内的文件系统名称;
-i : 使用ASCII的字符输出,不要使用复杂的编码(在某些环境下很有用);
-m : 同时输出该设备在/dev下面的权限信息(rwx的数据);
-p : 列出该设备的完整文件名,而不是仅列出最后的名字而已;
-t : 列出该磁盘设备的详细数据,包括磁盘阵列机制、预读写的数据量大小等。
UUID是全局唯一标识符(universally unique identifier),Linux会将系统内所有的设备都给予一个独一无二的标识符,这个标识符就可以拿来作为挂载或使用这个设备或文件系统。
parted device name print
MBR分区表请使用fdisk分区,GRP分区表请使用gdisk分区。
gdisk 设备名称
不管进行什么操作,只要离开gdisk时按下【q】,那么所有的操作都不会生效,相反,按下【w】就是写入、操作生效的意思。
使用【p】可以列出目前这块磁盘的分区表信息。
使用【d】可以删除一个分区。
这个gdisk只有root才能执行,使用的设备文件名请不要加上数字,因为磁盘分区是针对整个磁盘设备而不是某个分区。
partprobe -s
fdisk 设备名称
我们常听到的格式化其实应该称为创建文件系统(make filesystem)才合适,所以使用的命令是mkfs。
mkfs.xfs [-b bsize] [-d parms] [-i parms] [-l parms] [-f] [-r parms] 设备名称
选项与参数:
关于单元:下面只要谈到【数值】时,没有加单位则为Bytes值,可以用k、m、g、t、p(小写)等来解释比较特殊的是s这个单位它指的是扇区的【个数】。
-b : 后面接的是区块容量,可由512到64k,不过最大容量限制为Linux的4k;
-d : 后面接的是重要的data section的相关参数值,主要的值有:
agcount=数值 : 设置重要几个存储群组的意思(AG),通常与CPU有关。
agsize=数值 : 每个AG设置为多少容量的意思,通常agcount/agsize只选一个设置即可。
file : 指的是【格式化的设备是个文件而不是个设备】的意思。(例如虚拟磁盘)
size=数值 : data section的容量,亦即你可以不将全部的设备容量用完的意思。
su=数值 : 当有RAID时,那个stripe数值的意思,与下面的sw搭配使用。
sw=数值 : 当有RAID时,用于保存数据的磁盘数量(需扣除备份盘与备用盘)。
sunit=数值 : 与su相当,不过单位使用的是【几个sector(512Bytes大小)】的意思。
swidth=数值 : 就是su*sw的数值,但是以【几个sector(512Bytes大小)】来设置。
-f : 如果设备内已经有文件系统,则需要使用这个-f来强制格式化才行;
-i : 与inode有较相关的设置,主要的配置值有:
size=数值 : 最小是356Bytes最大是2k,一般保留256就足够使用了。
internal=[0|1] : log设备是否为内置?默认为1内置,如果要用外部设备,使用下面设置。
logdev=device : log设备为后面接的那个设备上面的意思,需设置internal=0才可。
size=数值 : 指定这块登录区的容量,通常最小得要有512个区块,大约2M以上才行。
-L : 后面接的这个文件系统的标头名称Label name的意思;
-r : 指定realtime section的相关设置值,常见的有:
extsize=数值 : 就是那个重要的extent数值,一般不需设置,但有RAID时,最好设置与swidth的数值相同较佳,最小为4K最大为1G。
磁盘阵列(RAID)就是通过将文件先细分为数个小型的分区区块(stripe)之后,然后将众多的stripes分别放到磁盘阵列里面的所有磁盘,所以一个文件是被同时写入到多个磁盘中,当然性能会更好一些。
为了文件的安全性,所以在这些磁盘里面,会保留数个(与磁盘阵列的规划有关)校验磁盘(parity disk),以及可能会保留一个以上的备用磁盘(spare disk),这些区块基本上会占用掉磁盘阵列的总容量,不过对于数据的安全会比较有保障。
那个分区区块stripe的数值大多介于4K和1M之间,这与你的磁盘阵列卡支持的选项有关。
stripe与你的文件数据容量以及性能相关性较高,
(1)当你的系统大多是大型文件时,一般建议stripe可以设置大一些,这样磁盘阵列读写的频率会降低,性能会提升。
(2)如果是用于系统,那么小文件比较多的情况下,stripe建议大约在64K左右可能会有较佳的性能。
如果想要格式化为ext4的传统Linux文件系统的话,可以使用mkfs.ext4这个命令。
mkfs.ext4 [-b bsize] [-L label] 设备名称
选项与参数:
-b : 设置区块的大小,有1K、2K、4K的容量;
-L : 后面接这个设备的标头名称。
mkfs其实是个综合命令而已,当我们使用mkfs -t xfs时,它就会跑去找mkfs.xfs相关的参数给我们使用。如果想知道系统还支持哪种文件系统的格式化功能,直接按[tab]就很清楚了。
//(找所有mkfs)
mkfs [tab] [tab]
xfs_repair [-fnd] 设备名称
选项与参数:
-f : 后面的设备其实是个文件而不是实体设备;
-n : 单纯检查并不修改文件系统的任何数据(检查而已);
-d : 通常用在单人维护模式下面,针对根目录(/)进行检查与修复的操作,很危险,不要随便使用。
xfs_repair可以检查/修复文件系统,不过,因为修复文件系统是个很庞大的任务。修复时该文件系统不能被挂载。
fsck是个综合命令,如果是针对ext4的话,建议直接使用fask.ext4来检测比较妥当。
fsck.ext4 [-pf] [-b 超级区块] 设备名称
选项与参数:
-p : 当文件系统在修复时,若有需要回复y的操作时,自动回复y来继续进行修复操作;
-f : 强制检查,一般来说,如果fsck没有发现任何unclean的标识,不会主动进入详细检查的,如果想要强制fsck详细检查,就得加上-f标识;
-D : 针对文件系统下的目录进行最佳化配置;
-b : 后面接超级区块的位置,一般来说这个选项用不到,但是如果你的超级区块因故损坏时,通过这个参数即可利用文件系统内备份的超级区块来尝试恢复,一般来说,超级区块备份在:1K区块放在8193,2K区块放在16384,4K区块放在32768。
注意:
通常只有身为root且你的文件系统有问题的时候才使用这个命令,否则在正常状况下使用此命令,可能会造成对系统的危害。
执行xfs_repair与fsck_ext4时,被检查的磁盘分区务必不可挂载到系统上,亦即是需要在卸载的状态。
挂载前,先确认几件事:
如果用来挂载的目录里面并不是空的,那么挂载了文件系统之后,原目录下的东西就会暂时地消失。
mount -a
mount [-l]
mount [-t 文件系统] LABEL='' 挂载点
mount [-t 文件系统] UUID='' 挂载点(推荐)
mount [-t 文件系统] 设备文件名 挂载点
选项与参数:
-a : 依照配置文件/etc/fstab的数据将所有未挂载的磁盘都挂载上来;
-l : 单纯的输入mount会显示目前挂载的信息,加上-l可增列Label名称;
-t : 可以加上文件系统种类来指定欲挂载的类型,常见的Linux支持类型有:xfs、ext3、ext4、reiserfs、vfat、iso9660(光盘格式)、nfs、cifs、smbfs(后三种为网络文件系统类型);
-n : 在默认的情况下,系统会将实际挂载的情况即时写入/etc/mtab中,以利其他程序的运行,但在某些情况下(例如单人维护模式)为了避免问题会刻意不写入,此时就得要使用 -n 选项;
-o : 后面可以接一些挂载时额外加上的参数。比方说账号、密码、读写权限等;
系统指定类型的文件系统才需要进行挂载测试:
Linux支持的文件系统的驱动程序都写在如下的目录中:
过去习惯使用设备文件名然后直接用该文件名挂载,不过近期以来比较建议使用UUID来识别文件系统,会比设备名称与标头名称还要更可靠,因为是独一无二的。
blkid /dev/vda4
(找出UUID后)
mount UUID = “...(略)” /data/xfs
blkid
(找出UUID后)
mount /dev/sr0 /data/xfs
光驱一挂载之后就无法退出光盘了,除非你将它卸载才能够退出。
类似于前面的CD或DVD光盘
整个目录树最重要的地方就是根目录,所以根目录根本就不能够被卸载。问题是,如果你的挂载参数要改变或是根目录出现【只读】状态时,如何重新挂载?最可能的处理方法就是重新启动(reboot)。不过你也可以这样做:
//将/重新挂载,并加入参数为rw与auto
mount -o remount,rw,auto /
重点是那个【-o remount,xx】的选项与参数。
另外,我们也可以利用mount来将某个目录挂载到另外一个目录。这并不是挂载文件系统,而是额外挂载某个目录的方法。虽然下面的方法也可以使用符号链接来做链接,不过在某些不支持符号链接的程序运行中,还是要通过这样的方法才行。
mount --bind /var /data/var
通过这个mount --bind的功能,您可以将某个目录挂载到其他目录,而并不是整个文件系统,所以从此进入/data/var就是进入/var的意思。
umount [-fn] 设备文件名或挂载点
选项与参数:
- -f : 强制卸载,可用在类似网络文件系统(NFS)无法读取到的情况下;
- -l : 立即卸载文件系统,比-f还强;
- -n : 不更新/etc/mtab情况下卸载。
就是直接将已经挂载的文件系统卸载,卸载之后,可以使用df或mount看看是否还存在于目录树中。卸载的方式,可以输入设备文件名或挂载点,均可接受。
通过文件的major与minor数值来代表设备,常见的磁盘文件名和代码如下:
磁盘文件名 | major | minor |
/dev/sda | 8 | 0-15 |
/dev/sdb | 8 | 16-31 |
/dev/loop0 | 7 | 0 |
/dev/loop1 | 7 | 1 |
mknod 设备文件名 [bcp] [Major] [Minor]
选项与参数:
设备种类:
- b : 设置设备名称成为一个外接存储设备文件,例如磁盘等;
- c : 设置设备名称成为一个外接输入设备文件,例如鼠标/键盘等;
- p : 设置设备名称成为一个FIFO文件。
Major : 主要设备代码;
Minor : 次要设备代码。
xfs_admin [-lu] [-L label] [-U uuid] 设备文件名
选项与参数:
- -l : 列出这个设备的labei name;
- -u : 列出这个设备的UUID;
- -L : 设置这个设备的Label name;
- -U : 设置这个设备的UUID。
tune2fs [-l] [-L label] [-U uuid] 设备文件名
选项与参数:
- -l : 类似dump2fs -h的功能,将superblock内的数据读出来;
- -L : 修改LABEL name;
- -U : 修改UUID。
挂载的一些限制:
以/etc/fstab为例
cat /etc/fstab
输出六栏,一定要背下来,如下:
[设备/UUID等] [挂载点] [文件系统] [文件系统参数] [dump] [fsck]
第一栏:磁盘设备文件名/UUID/LABEL name,主要有三个项目
第二栏:挂载点(mount point)
挂载点一定是目录。
在手动挂载时可以让系统自动测试挂载,但在这个文件当中我们必须要手动写入文件系统才行,包括xfs、ext4,vfat、reiserfs、nfs等。
参数 | 内容意义 |
async/sync 异步/同步 |
设置磁盘是否以异步方式运行,默认为async(性能较佳)。 |
auto/noauto 自动/非自动 |
当执行mount -a时,此文件系统是否会被主动测试挂载,默认为auto。 |
rw/ro 可擦写/只读 |
让该分区以可读写或只读的状态挂载上来,如果你想要分享的数据是不给用户随意变更,这里也能够设置为只读,则不论在此文件系统的文件是否设置w权限,都无法写入。 |
exec/noexec 可执行/不可执行 |
限制在此文件内是否可以进行【执行】的工作?如果是纯粹用来存储数据的目录,那么可以设置为noexec会比较安全。不过,这个参数也不能随便使用,因为你不知道该目录下是否默认会有执行文件。 |
user/nouser 允许/不允许用户挂载 |
是否允许用户使用mount命令来挂载?一般而言,我们当然不希望一般身份的user能使用mount,因为太不安全了,因此这里应该设置为nouser。 |
suid/nosuid 具有/不具有suid权限 |
该文件系统是否允许SUID的存在?如果不是执行文件放置目录,也可以设置为nosuid来取消这个功能。 |
defaults | 同时具有rw、suid、dev、exec、auto、nouser、async等参数,基本上,默认情况使用defaults设置即可。 |
dump是一个用来作为备份的命令,不过现在有太多的备份方案,所以这个项目可以不要理会,直接输入0就好。
早期启动的流程中,会有一段时间去检验本机的文件系统,看着文件系统是否完整(clean)。不过这个阶段主要是通过fsck去完成,我们现在用的xfs文件系统就没有办法适用,因为xfs会自己进行检验,不需要额外进行这个操作,所以直接填0就好了。
实际文件系统的挂载是记录到/etc/mtab与/proc/mounts这两个文件中的。
mount -o loop /temp/xx /xx
主要是用loop命令进行挂载。
安装Linux时一定需要的两个硬盘分区,一个是根目录,另外一个是内存交换分区。
可以使用如下方法来建立内存交换分区:
步骤:
parted [设备] [命令[参数]]
选项与参数:
命令功能:
#捌、第八章-文件与文件系统的压缩
压缩后与压缩的文件所占用的磁盘空间大小,就可以称为是压缩比。
几个常见的压缩文件扩展名:
gzip可以说是应用最广的压缩命令了,目前gzip可以解开compress、zip与gzip等软件所压缩的文件,至于gzip所建立的压缩文件为*.gz。
gzip [-cdtv#] 文件名
zcat 文件名.gz
选项与参数:
当你使用gzip进行压缩时,在默认的状态下原本的文件会被压缩成为.gz后缀的文件,源文件就不再存在了。
cat/more/less可以使用不同的方式来读取纯文本文件,那个zcat/zmore/zless则可以对应于cat/more/less的方式来读取纯文本文件被压缩后的压缩文件。
bzip2是为了替换gzip并提供更佳的压缩比。
bzip2 [-cdkzv#] 文件名
bzcat 文件名.bgz
选项与参数:
xz这个压缩比更高。
xz [-dtlkc#] 文件名
xcat 文件名.xz
选项与参数:
tar [-z|-j|-J] [cv] [-f 待建立的新文件名] filename... (打包与压缩)
tar [-z|-j|-J] [tv] [-f 既有的tar文件名] (查看文件名)
tar [-z|-j|-J] [xv] [-f 既有的tar文件名] [-C 目录] (解压缩)
选项与参数:
最简单的tar命令:
如果仅是打包而已,就是【tar -cv -f file.tar】而已,这个文件我们称为**tarfile,如果还有进行压缩的支持,例如【tar -jcv -f file.tar.bz2】时,我们称为tarball**。
特殊应用:
在tar使用中,有一种方式最特殊,那就是通过标准输入输出的数据流重定向(standard input/standard output),以及管道命令(pipe)的方式,将待处理的文件一边打包一边解压缩到目标目录。
xfsdump的功能很强,除了可以进行文件系统的完整备份(full backup)之外,还可以进行增量备份(incremental backup)。
第一次备份一定是完整备份,完整备份在xfsdump当中被定义为level0。等到第二次备份时,/home文件系统内的数据已经与level0不一样了,而level1仅只是比较目前的文件系统与level0之间的差异后,备份有变化过的文件。
使用xfsdump时,请注意下面的限制:
xfsdump [-L S_label] [-M M_label] [-l #] [-f 备份文件] 待备份数据
xfsdump -I
选项与参数:
进行增量备份时,一定要进行过完整备份后(-l 0)才能够继续有其他增量备份(-l 1~9)的能力。
备份文件在急用时可以恢复系统的重要数据,xfsdump的恢复使用的是xfsrestore这个命令。
xfsrestore -I (用来查看备份文件)
xfsrestore [-f 备份文件] [-L S_label] [-s] 待恢复目录 (单一文件全系统恢复)
xfsrestore [-f 备份文件] -r 待恢复目录 (通过增量备份文件来恢复系统)
xfsrestore [-f 备份文件] -i 待恢复目录 (进入交互模式)
选项与参数:
通常的做法是:
利用一般数据光盘镜像文件,mkisofs的使用方法如下:
mkisofs [-o 镜像文件] [-Jrv] [-V vol] [-m file] 待备份文件... -graft-point isodir=systemdir ...
选项与参数:
光盘的格式一般称为iso9660,这种格式一般仅支持旧版的DOS文件名,亦即文件名只能以8.3(文件名8个字符,扩展名3个字符)的方式存在。
所有要被加到镜像文件中的文件都会被放置到镜像文件中的根目录,可以利用如下的方法来定义位于镜像文件中的目录:
wodim被链接到cdrecord中,建议还是改用wodim比较干脆。
wodim --devices dev=/dev/sr0... (查询刻录机的bus位置)
wodim -v dev=/dev/sr0 black=[fast|all] (抹除重复读写盘)
wodim -v dev=/dev/sr0 -format (格式化DVD+RW)
wodim -v dev=/dev/sr0 [可用选项功能] file.iso
选项与参数:
–devices : 用在扫描磁盘总线并找出可用的刻录机,后续的设备为ATA接口;
-v : 在cdrecord运行的过程中显示过程;
dev=/dev/sr0 : 可以找出此光驱的bus地址,非常重要;
black=[fast|all] : black为抹除可重复写入的CD/DVD-RW这种格式的DVD而已;
-format : 对光盘进行格式化,但是仅针对DVD+RW这种格式的DVD而已。
[可用选项功能]主要是写入CD/DVD时可使用的选项,常见的选项包括有:
针对DVD的选项功能:
dd最大的功能在于备份,因为dd可用读取磁盘设备的内容(几乎是直接读取扇区),然后将整个设备备份成一个文件。
dd if="input_file" of="output_file" bs="block_size" count="number"
选项与参数:
一般来说,cpio要配合类似find等可以查找文件的命令来告知cpio该被备份的数据在哪里。
cpio -ovcB > [file|device] (备份)
cpio -ivcdu < [file|device] (还原)
cpio -ivct < [file|device] (查看)
选项与参数:
备份会用到的:
还原会用到的:
查看会用到的:
为何要学vim,因为:
基本上,vi的使用分为三种模式,分别是一般命令模式、编辑模式与命令行模式。作用分别是:
一般命令模式(command mode)
以vi打开一个文件就直接进入一般命令模式(简称一般模式)了。在这个模式中,你可以使用【上下左右】按键来移动光标,可以使用【删除字符】或【删除整行】来处理文件内容,也可以使用【复制、粘贴】来处理你的文件内容。
编辑模式(insert mode)
在一般模式中可以进行删除、复制、粘贴等的操作,但是却无法编辑文件的内容。要等到按下【i、l、o、O、a、A、r、R】等任何一个字母之后才会进入编辑模式。注意了,通常在Linux中,按下这些按键时,在界面的左下方会出现【INSERT】或【REPLACE】的字样,此时才可以进行编辑,而如果要回到一般模式时,则必须按下【Esc】这个按键即可退出编辑模式。
命令行模式(command-line mode)
在一般模式中,输入【: / ?】三个中的任意一个按钮,就可以将光标移动到最下面那一行。在这个模式当中,可以提供你【查找数据】的操作,而读取、保存、批量替换字符、退出vi、显示行号等操作则是在此模式中完成的。
如果你想要使用vi来建立一个名为welcome.txt的文件时,你可以这样做:
/bin/vi welcome.txt
在一般模式之中,只要按下i、o、a等字符就可以进入编辑模式了,在编辑模式当中,你可以发现在左下角状态栏中会出现-INSERT-的字样,那就是可以输入任何字符的提示。这个时候,键盘上除了[Esc]这个按键之外,其他的按键都可以视作一般的输入按钮,所以你可以进行任何的编辑。
按下[Esc]这个按键,你会发现-INSERT-不见了。
保存(write)并退出(qiut)的命令很简单,输入【:wq】即可保存退出。
移动光标的方法 | |
h或向左箭头键(←) | 光标向左移动一个字符 |
j或向左箭头键(↓) | 光标向下移动一个字符 |
k或向左箭头键(↑) | 光标向上移动一个字符 |
l或向左箭头键(→) | 光标向右移动一个字符 |
如果要多次移动,例如向下移动30行,可以使用30j或30↓ | |
[Ctrl]+[f] | 屏幕【向下】移动一页,相当于[Page Down]按键(常用) |
[Ctrl]+[b] | 屏幕【向上】移动一页,相当于[Page Up]按键(常用) |
[Ctrl]+[d] | 屏幕【向下】移动半页 |
[Ctrl]+[u] | 屏幕【向上】移动半页 |
+ | 光标移动到非空格符的下一行 |
- | 光标移动到非空格符的上一行 |
n(n加空格键) | 那个n表示【数字】,按下数字再按下空格键,光标会向右移动这一行的n个字符,例如20这样 |
0或功能键[Home] | 数字【0】,移动到这一行的最前面字符处(常用) |
$或功能键[End] | 移动到这一行的最后面字符处(常用) |
H | 光标移动到这个屏幕的最上方那一行的第一个字符 |
M | 光标移动到这个屏幕的中央那一行的第一个字符 |
L | 光标移动到这个屏幕的最下方那一行的第一个字符 |
G | 光标移动到这个文件的最后一行(常用) |
nG | n为数字,移动到这个文件的第n行 |
gg | 移动到这个文件的第一行,相当于1G(常用) |
n(n加Enter键) | 那个n表示【数字】,按下数字再按下Enter键,光标向下移动n行(常用) |
查找与替换 | |
/word | 向光标之下寻找一个名称为word的字符串,word可以换成其他的字符串 |
?word | 向光标之上寻找一个名称为word的字符串,word可以换成其他的字符串 |
n | 这个n是英文按键,代表【重复前一个查找的操作】。 |
N | 这个N是英文按键,与n相反,代表【反向前一个查找的操作】。 |
使用/word配合n及N是非常有帮助的,可以让你重复的找到一些你查找的关键词。 | |
:n1,n2s/word1/word2/g | n1与n2为数字,在第n1与n2行之间寻找word1这个字符串,并将该字符串替换为word2。(常用) |
:1,$s/word1/word2/g | 从第一行到最后一行寻找word1这个字符串,并将该字符串替换为word2。(常用) |
:1,$s/word1/word2/gc | 从第一行到最后一行寻找word1这个字符串,并将该字符串替换为word2,且在替换前显示提示符给用户确认(confirm)是否需要替换。 |
删除、复制与粘贴 | |
x与X | 在一行当中,x为向后删除一个字符(相当于[del]按键),X为向前删除一个字符(相当于[Backspace]即退格键)。(常用) |
nx | n为数字,连续向后删除n个字符。(常用) |
dd | 删除(剪切)光标所在的那一整行。(常用) |
ndd | n为数字,删除(剪切)光标所在的向下n行。(常用) |
d1G | 删除(剪切)光标所在到第一行的所有数据。 |
dG | 删除(剪切)光标所在到最后一行的所有数据。 |
d$ | 删除(剪切)光标所在处,到该行的最后一个字符。 |
d0 | 那个是数字0,删除(剪切)光标所在处,到该行的最前面一个字符。 |
yy | 复制光标所在的那一行。(常用) |
nyy | n为数字,复制光标所在的向下n行。(常用) |
y1G | 复制光标所在到第一行的所有数据。 |
yG | 复制光标所在到最后一行的所有数据。 |
y0 | 那个是数字0,复制光标所在的那个字符到该行行首的所有数据。 |
y$ | 复制光标所在的那个字符到该行行尾的所有数据。 |
p与P | p为将已复制的数据在光标下一行粘贴,P则为贴在光标上一行。(常用) |
J | 将光标所在行与下一行的数据结合成同一行。 |
c | 重复删除多个数据。例如向下删除10行(10cj)。 |
u | 恢复前一个操作。(常用) |
[Ctrl]+r | 重做上一个操作。(常用) |
. | 这就是小数点,重复前一个操作。(常用) |
进入插入或替换的编辑模式 | |
i与l | 进入插入模式(Insert mode): i为【从目前光标所在处插入】,l为【在目前所在行的第一个非空格符处开始插入】。(常用) |
a与A | 进入插入模式(Insert mode): a为【从目前光标所在的下一个字符处开始插入】,A为【从光标所在行的最后一个字符处开始插入】。(常用) |
o与O | 进入插入模式(Insert mode): 这是英文字母o的大小写,o为【从目前光标所在的下一行处开始插入】,O为【在目前光标所在处的上一行插入新的一行】。(常用) |
r与R | 进入插入模式(Insert mode): r为【只会替换光标所在的那一个字符一次】,R为【会一直替换光标所在的文字,直到按下Esc为止】。(常用) |
上面那些按键中,在vi界面的左下角会出现【--INSERT——】或【--REPLACE--】的字样。 | |
[Esc] | 退出编辑模式,回到一般命令模式。(常用) |
命令行模式的保存、退出等命令 | |
:w | 将编辑的数据写入硬盘文件中。(常用) |
:w! | 若文件属性为【只读】时,强制写入该文件。不过,到底能不能写入,还是跟你对接文件的文件权限有关。 |
:q | 退出vi。(常用) |
:q! | 若曾修改文件,又不想保存,使用!为强制出不保存。(常用) |
注意一下,那个感叹号(!)在vi当中,常常具有【强制】的意思。 | |
:wq | 保存后退出,若为:wq!则为强制保存后退出。(常用) |
ZZ | 这是大写的Z,若文件没有修改,则不保存退出,若文件已经被修改过,则保存后退出。 |
:w[filename] | 将编辑的数据保存成另一个文件(类似另存新文件)。 |
:r[filename] | 在编辑的数据中,读入另一个文件的数据,亦即将【filename】这个文件内容加到光标所在行后面。 |
:n1,n2w[filename] | 将n1到n2的内容保存为filename这个文件。 |
:!command | 暂时退出vi到命令行模式下执行command的显示结果。例如【:!ls /home】即可在vi当中查看/home下面以ls输出的文件信息。 |
vim环境的修改 | |
:set nu | 显示行号,设置之后,会在每一行的前缀显示该行的行号。 |
:set nonu | 与set nu相反,为取消行号。 |
特别注意的是,在vi中,【数字】是很有意义的,数字通常代表重复做几次的意思,也有可能是代表去到第几个什么什么的意思。
vim具有颜色显示的功能,并且还支持许多的程序语法(syntax)。
vim还可以直接进行【程序除错(dubug)】的功能。(具体看书的案例)
自行实验,列举一下按键说明:
可视区块的按键意义 | |
v | 字符选择,会将光标经过的地方反白选择。 |
V | 行选择,会将光标经过的行反白选择。 |
[Ctrl]+v | 可视区块,可以用矩形的方式选择数据。 |
y | 将反白的地方复制起来。 |
d | 将反白的地方删除掉。 |
p | 将刚刚复制的区块,在光标所在处粘贴。 |
自行实验,列举一下按键说明:
多文件编辑的按键 | |
:n | 编辑下一个文件。 |
:N | 编辑上一个文件。 |
:files | 列出目前这个vim开启的所有文件。 |
如何划分窗口并放入文件?在命令行模式输入【:sp{filename}】即可。如果想要在新窗口启动另一个文件,就加入文件名,否则仅输入:sp时,出现的则是同一个文件在两个窗口间。
多窗口情况下的按键功能。 | |
:sp[filename] | 打开一个新窗口,如果有加filename,表示在新窗口创建一个新文件,否则表示两个窗口为同一个文件内容(同步显示)。 |
[ctrl]+w+j [ctrl]+w+↓ |
按键的用法是:先按下[ctrl]不放,再按下w后放开所有按键,之后再按下j(或向下箭头键),则光标可移动到下方的窗口。 |
[ctrl]+w+k [ctrl]+w+↑ |
按键的用法是:先按下[ctrl]不放,再按下w后放开所有按键,之后再按下k(或向上箭头键),则光标可移动到上方的窗口。 |
[ctrl]+w+q | 其实就是:q结束退出的作用。 |
主要vim补全功能,大致有下面几个:
组合键 | 补全的内容 |
[ctrl]+x -> [ctrl]+n | 通过目前正在编辑的这个【文件的内容文字】作为关键词,予以补齐。 |
[ctrl]+x -> [ctrl]+f | 以当前目录内的【文件名】作为关键词,予以补充。 |
[ctrl]+x -> [ctrl]+o | 以扩充名作为语法补充,以vim内置的关键词,予以补齐。 |
vim会主动地将你曾经做过的操作记录下来,好让你下次可以轻松地作业,这个记录操作的文件就是:~/.viminfo。
如果想了解目前设置的环境设置参数的设置值,可以在一般命令模式时输入【:set all】来查看。
vim的环境设置参数 | |
:set nu :set nonu |
就是设置与取消行号。 |
:set hlsearch :set nohlsearch |
hlsearch就是high light search(高亮度查找),这个就是设置是否将查找的字符串反白的设置值,默认值是hlsearch。 |
:set autoindent :set noautoindent |
是否自动缩进?autoindent就是自动缩进。 |
:set backup | 是否自动保存备份文件?一般是nobackup的,如果设置backup的话,那么当你修改任何一个文件时,则源文件会被另存为一个文件名为filename~的文件。举例来说,我们编辑hosts,设置:set backup,那么当修改hosts时,在同目录下,就会产生hosts~文件名的文件,记录原始的hosts文件内容。 |
:set ruler | 还记得我们提到的右下角的一些状态栏说明?这个ruler就是在显示或不显示该设置值的。 |
:set showmode | 这个则是,是否要显示--INSERT--之类的字眼在左下角的状态栏。 |
:set backspace=(012) | 一般来说,如果我们按下i进入编辑模式后,可以利用退格键(Backspace)来删除任何字符。但是,某些Linux发行版则不许如此。此时,可以通过backspace来设置,当backspace为2时,就是可以删除任意值;0或1时,仅可删除刚刚输入的字符,而无法删除原本就已经存在的文字。 |
:set all | 显示目前所有的环境参数设置值。 |
:set | 显示与系统默认值不同的设置参数,一般来说就是你有自行变动过的设置参数。 |
:syntax on :syntax off |
是否依据程序相关语序显示不同颜色?举例来说,在编辑一个纯文本文件时,如果开头是以#开始,那么该行就会变成蓝色。如果你懂得写程序,那么这个:syntax on还会主动的帮你除错。但是,如果你仅是编写纯文本文件,要避免颜色对你的屏幕产生的干扰,则可以取消这个设置。 |
:set bg=dark :set bg=light |
可用以显示不同的颜色色调,默认是【light】,如果你常常发现注释的深蓝色实字体在很不容易看,那么这里可以设置为dark,试看看,会有不同的样式。 |
整体vim的设置值一般是放置在/ect/vimrc这个文件中,不过,不建议你修改它,你可以修改~/.vimrc这个文件(默认不存在,请你自行手动建立),将你所希望的设置值写入。
很重要!!!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vVOasmRC-1650619261260)(https://thumbnail0.baidupcs.com/thumbnail/48e739054k4ca681e3334fa5d430535b?fid=1531607901-250528-531870224381011&time=1648717200&rt=sh&sign=FDTAER-DCb740ccc5511e5e8fedcff06b081203-%2Btwyh3UG%2Fz%2BhHyfLF8Qk2d%2FPtD8%3D&expires=8h&chkv=0&chkbd=0&chkpc=&dp-logid=8998667545598201561&dp-callid=0&file_type=0&size=c710_u400&quality=100&vuk=-&ft=video)]
LANG=zh_CN.gb18030
export LC_ALL=zh_CN.gb18030
然后在终端工具栏的 【终端】 --> 【设置字符编码】 --> 【中文(简体)】 选项点选一下。
dos2unix [-kn] file [newfile] //DOS转unix
unix2dos [-kn] file [newfile] //unix转DOS
选项与参数:
iconv --list
iconv -f 原本编码 -t 新编码 filename [-o newfile]
选项与参数:
管理整个计算机硬件的其实就是操作系统的内核(Kernel),这个内核是需要被保护的。
我们必须要通过Shell将我们输入的命令与内核沟通,好让内核可以控制硬件来正确无误地工作。
bash主要的优点如下:
历史命令(history):(查询曾经做过的操作)
只要在命令行按【上下键】就可以找到前后一个输入的命令。
这个记录在哪呢?就在家目录内的.bash_history,不过,~/.bash_history记录的是前一次登录以前执行过的命令,而至于这一次登录所执行的命令都被缓存在内存中,当你成功的注销系统后,该命令才会记录到.bash_history当中。
命令与文件补齐功能:([Tab]按键的好处)
命令别名设置功能:(alias)
可以直接执行命令来设置命令的别名:
alias lm = 'ls -al'
任务管理、前台、后台控制:(job control、foreground、background)
后面讲到。
程序化脚本:(shell scripts)
后面讲到。
通配符:(Wildcard)
除了完整的字符串之外,bash还支持许多的通配符来帮助用户查询与命令执行。
举例来说,想知道/usr/bin下面有多少以X为开头的文件,使用【ls -l /usr/bin/X*】。这个*就是通配符。
type
选项与参数:
组合键 | 功能与示范 |
[ctrl]+u/[ctrl]+k | 分别是从光标处向前删除命令串([ctrl]+u)及向后删除命令串([ctrl]+k) |
[ctrl]+a/[ctrl]+e | 分别是让光标移动到整个命令串的最前面([ctrl]+a)或最后面([ctrl]+e) |
简单的定义:变量就是以一组文字或符号等,来替代一些设置或一串保留的数据。
变量在被使用时,前面必须要加上美元符号【$】才行,举例来说,用echo读出变量:
echo $HOME或是echo ${HOME} //推荐使用后者
在bash当中,当一个变量名称尚未被设置时,默认的内容是【空】
变量的设置规则:
变量与变量内容以一个等号【=】来连接;
等号两边不能直接接空格;
变量名称只能是英文字母与数字,但是开头字符不能是数字;
变量的内容若有空格,可使用双引号【"】或单引号【'】将变量内容结合起来,但
双引号内的特殊字符如$等,可以保留原本的特性;
单引号内的特殊字符则仅为一般字符(纯文本)。
可用转义符【\】将特殊符号(如[Enter]、$、\、空格、'等)变成一般字符;
在一串命令的执行中,还需要借由其他额外的命令所提供的信息时,可以使用反单引号【命令
】或【$(命令)】。特别注意,那个`是键盘数字1左边的那个;
若该变量为扩增变量内容时,则可用" 变 量 名 称 " 或 变量名称"或 变量名称"或{变量}累加内容;
若该变量需要在其他子程序执行,则需要以export来使变量变成环境变量;
通常大写字符为系统默认变量,自行设置变量可以使用小写字符,方便判断(纯粹依照用户兴趣与嗜好);
取消变量的方法为使用unset:【unset 变量名称】。
env是environment(环境)的简写。
- HOME
代表用户的根目录。
- SHELL
告知我们,目前这个环境使用的SHELL是哪个程序?Linux默认使用/bin/bash。
- HISTSIZE
这个与历史命令有关,即我们曾经执行过的命令可以被系统记录下来,而记录的条数则是由这个值来设置的。
- MAIL
当我们使用mail这个命令在收信时,系统会去读取的邮箱文件(mailbox)。
- PATH
就是执行文件查找的路径,目录与目录中间以冒号(:)分割,由于文件的查找是依序由PATH的变量内的目录来查询的,所以,目录的顺序也是重要的。
- LANG
这个重要,就是语序数据,很多信息会用到它。我们中文编码通常是zh_CN.GB2312或是zh_CN.UTF-8。
- RANDOM
这个玩意就是随机数的变量。我们可以通过这个随机数文件相关的变量($RANDOM)来随机取得随机数。在BASH的环境下,这个RANDOM变量的内容,介于0~32767。
如果想使用0~9的随机数数值,则利用declare声明数值类型:
```
declare -i number=$RANDOM*10/32768;echo number
```
基本上,在Linux默认的情况中,使用{大写的字母}来设置的变量一般为系统内定需要的变量。
- PS1:(提示字符的设置)
这是PS1(数字1),这个东西就是我们的命令提示字符。当我们每次按下[Enter]按键去执行某个命令后,最后要再次出现提示字符时,就会主动去读取这个变量值。
- \d:可显示出【星期 月 日】的日期格式,如【Mon Feb 2】;
- \H:完整的主机名;
- \h:仅取主机名在第一个小数点之前的名字;
- \t:显示时间,为24小时格式的【HH:MM:SS】;
- \T:显示时间,为12小时格式的【HH:MM:SS】;
- \A:显示时间,为24小时格式的【HH:MM】;
- \@:显示时间,为12小时格式的【am/pm】格式;
- \u:目前用户的账户名称;
- \v:BASH的版本信息;
- \w:完整的工作目录名称,由根目录写起的目录名称,但根目录会以~替换;
- \W:利用basename函数取得工作目录名称,所以仅会列出最后一个目录名;
- \#:执行的第几个命令;
- \$:提示字符,如果是root时,提示字符为#,否则就是$;
- $(关于本shell的PID):美元符号本身也是个变量。这个东西代表的是目前这个shell的进程号,即所谓的PID(Process ID)。
- ?(关于上个执行命令的返回值):当我们执行某些命令时,这些命令都会返回一个执行后的代码。一般来说,如果成功的执行该命令,则会返回一个0值,如果执行过程发生错误,就会返回错误代码才对,一般就是以非0的数值来替换;
- OSTYPE,HOSTTYPE,MACHTYPE(主机硬件与内核的等级)。
子进程仅会继承父进程的环境变量,子进程不会继承父进程的自定义变量。
read [-pt] variable
选项与参数:
read之后不加任何参数,直接加上变量名称,那么下面就会主动出现一个空白行等待你的输入。
declare或typeset是一样的功能,就是声明变量的类型。如果使用declare后面并没有接任何参数,那么bash就会主动的将所有的变量名称与内容通通显示出来,就好像使用set一样。
declare [-aixr] variable
选项与参数:
bash对于变量有几个基本的定义:
变量类型默认为字符串,所以若不指定变量类型,则1+2为一个字符串而不是计算式,所以上述第一个执行的结果才会出现那种情况;
bash环境中的数值运算,默认最多仅能达到整数状态,所以1/3结果是0。
数组(array)变量类型
数组的设置方式如下:
var[index]=content
index是索引,写数字。
一般来说,建议直接以 ${数组} 的方式来读取,比较正确无误。
ulimit [-SHacdfltu] [配额]
选项与参数:
变量设置方式 | 说明 |
${变量#关键词} ${变量##关键词} |
若变量内容从头开始的数据符合【关键词】,则将符合的最短数据删除 若变量内容从头开始的数据符合【关键词】,则将符合的最长数据删除 |
${变量%关键词} ${变量%%关键词} |
若变量内容从尾向前的数据符合【关键词】,则将符合的最短数据删除 若变量内容从尾向前的数据符合【关键词】,则将符合的最长数据删除 |
${变量/旧字符串/新字符串} ${变量//旧字符串/新字符串} |
若变量内容符合【旧字符串】则【第一个旧字符串会被新字符串替换】 若变量内容符合【旧字符串】则【全部的旧字符串会被新字符串替换】 |
变量设置方式 | str没有设置 | str为空字符串 | str已设置非为空字符串 |
var=${str-expr} | var=expr | var= | var=$str |
var=${str:-expr} | var=expr | var=expr | var=$str |
var=${str+expr} | var= | var=expr | var=expr |
var=${str:+expr} | var= | var= | var=expr |
var=${str=expr} | str=expr var=expr |
str不变 var= |
str不变 var=$str |
var=${str:=expr} | str=expr var=expr |
str=expr var=expr |
str不变 var=$str |
var=${str?expr} | expr输出至stderr | var= | var=$str |
var=${str:?expr} | expr输出至stderr | expr输出至stderr | var=$str |
alias lm='ls -al'
unalias lm
history [n]
history [-c]
history [-raw] histfiles
选项与参数:
!number
!command
!!
选项与参数:
命令运行的顺序:
login与non-login shell
/etc/profile(login shell才读)
这是每个用户登录取得bash时一定会读取的配置文件
- PATH:会根据UID决定PATH变量要不要含有sbin的系统命令目录;
- MAIL:根据账号设置好用户的mailbox到 /var/spool/mail 账号名;
- USER:根据用户的账号设置此变量内容;
- HOSTNAME:根据主机的hostname命令决定此变量内容;
- HISTSIZE:历史命令记录条数,CentOS7.x设置为1000;
- umask:包括root默认为022,而一般用户为002等。
其实这是个目录内的众多文件。
这个文件是由 /etc/profile.d/lang.sh 调用的,这也是我们决定bash默认使用何种语系的重要配置文件。
bash的login shell情况下所读取的整体环境配置文件其实只有 /etc/profile。
在login shell的bash环境中,所读取的个人偏好配置文件其实主要有三个,分别是:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
source 配置文件文件名
. 配置文件文件名
利用source或小数点(.)都可以将配置文件的内容读进来目前的shell环境中。
当你取得non-login shell时,该bash配置文件仅会读取~/.bashrc而已。
/etc/bashrc 帮我们的bash定义出下面的定义:
- 根据不同的UID设置umask的值;
- 根据不同的UID设置提示字符(就是PS1变量);
- 调用 /etc/profile.d/*.sh。
这个文件的内容规范了使用man的时候,man page的路径到哪里去寻找。
默认情况下,我们的历史命令就记录在这里。
这个文件则记录了【当我注销bash后,系统再帮我做完什么操作后才离开】的意思。
stty是setting tty终端的意思。
stty [-a]
选项与参数:
在查询到列表中,如果出现 ^ 表示[Ctrl]那个按键的意思。
几个重要关键词的意义:
- intr:发送一个interrupt(中断)的信号给目前正在run的程序(就是终止);
- qiut:发送一个qiut的信号给目前正在run的程序;
- erase:向后删除字符;
- kill:删除在目前命令行上的所有文字;
- eof:End of file的意思,代表【结束输入】;
- start:在某个程序停止后,重新启动它的output;
- stop:停止目前屏幕的输出;
- susp:送出一个terminal stop的信号给正在运行的程序。
set [-uvCHhmBx]
选项与参数:
bash默认组合键如下:
组合按键 | 执行结果 |
Ctrl+C | 终止目前的命令 |
Ctrl+D | 输入结束(EOF),例如邮件结束的时候 |
Ctrl+M | 就是回车 |
Ctrl+S | 暂停屏幕的输出 |
Ctrl+Q | 恢复屏幕的输出 |
Ctrl+U | 在提示字符下,将整列命令删除 |
Ctrl+Z | 暂停目前的命令 |
在bash的操作环境中还有一个非常有用的功能,那就是通配符(wildcard)。
符号 | 意义 |
* | 代表【0个到无穷多个】。 |
? | 代表【一定有一个】任意字符。 |
[] | 同样代表【一定有一个在括号内】的字符(非任意字符)。 |
[-] | 若有减号在中括号内时,代表【在编码顺序内的所有字符】。 |
[^] | 若中括号内的第一个字符为指数符号(^),那表示【反向选择】。 |
符号 | 内容 |
# | 注释符号:这个最常用被使用在脚本当中,视为说明,在后的数据均不执行。 |
\ | 转义符:将【特殊字符或通配符】还原成一般字符。 |
| | 管道(pipe):分割两个管道命令的符号。 |
; | 连续命令执行分隔符:连续性命令的界定。 |
~ | 用户的家目录。 |
$ | 使用变量前导符:亦即是变量之前需要加的变量替换值。 |
& | 任务管理(job control):将命令变成后台任务。 |
! | 逻辑运算意义上的【非】not的意思。 |
/ | 目录符号:路径分割的符号。 |
>、>> | 数据流重定向:输出定向,分别是【替换】与【累加】。 |
<、<< | 数据流重定向:输入定向。 |
'' | 单引号,不具有变量替换的功能($变为纯文本)。 |
"" | 具有变量替换的功能,($可保留相关功能)。 |
`` | 两个【`】中间为可以先执行的命令,亦可使用$()。 |
() | 在中间为子shell的起始与结束。 |
{} | 在中间为命令区块的组合。 |
简单地说,标准输出指的是命令执行所返回的正确信息,而标准错误输出可理解为命令执行失败后,所返回的错误信息。
数据流重定向的功能,数据流重定向可以将standard output(简称stdout)与standard error output(简称stderr)分别传送到其他的文件或设备,而分别传送所用的特殊字符则如下所示:
- 标准输入(stdin):代码为0,使用 < 或 << ;
- 标准输出(stdout):代码为1,使用 > 或 >> ;
- 标准错误输出(stderr):代码为2,使用 2> 或 2>> ;
文件的建立方式是:
- 该文件若不存在,系统会自动地将它建立起来;
- 当这个文件存在的时候,那么系统就会先将这个文件内容清空,然后再将数据写入;
- 也就是若以 > 输出到一个已存在的文件中,这个文件就会被覆盖掉。
标准输出:
- 1> : 以覆盖的方法将【正确的数据】输出到指定的文件或设备上;
- 1>> : 以累加的方法将【正确的数据】输出到指定的文件或设备上;
- 2> : 以覆盖的方法将【错误的数据】输出到指定的文件或设备上;
- 2>> : 以累加的方法将【错误的数据】输出到指定的文件或设备上;
将正确与错误数据通通写入同一个文件的方法
//将命令的数据全部写入名为list的文件中
find /home -name .bashrc > list 2> list <==错误
find /home -name .bashrc > list 2>&1 <==正确
find /home -name .bashrc &> list <==正确
上述表格第一行错误的原因是,由于两股数据同时写入一个文件,又没有使用特殊的语法,此时两股数据可能会交叉写入该文件内,造成次序的错乱。
一般来说,使用 2>&1 的方式。
standard input: < 与 <<
cat > catfile << "eof"
代表输入 oef 关键字后,此次输入就结束了。
为何要使用命令输出重定向呢?,因为:
cmd;cmd(不考虑命令相关性的连续命令执行)
$?(命令返回值)与&&或||
若前一个命令执行的结果为正确,在Linux下面会返回一个$?=0的值。
命令执行情况 | 说明 |
cmd1&&cmd2 | 1.若cmd1执行完毕且正确执行($?=0),则开始执行cmd2。 2.若cmd1执行完毕且为错误执行($?≠0),则cmd2不执行。 |
cmd1||cmd2 | 1.若cmd1执行完毕且正确执行($?=0),则cmd2不执行。 2.若cmd1执行完毕且为错误执行($?≠0),则开始执行cmd2。 |
管道命令使用的是【|】这个界定符号。
管道命令与【连续执行命令】是不一样的。
这个管道命令【|】仅能处理经由前面一个命令传来的正确信息,也就是标准输出的信息,对于标准错误并没有直接处理的能力。
在每个管道后面接的第一个数据必定是【命令】,而且这个命令必须要能够接受标准输入的数据才行,这样的命令才可为管道命令,主要有两个比较注意的地方:
选取信息通常是针对【一行一行】来分析的。
cut -d '分割字符' -f fields <==用于有特定分割字符
cut -c 字符区间 <==用于排列整齐的信息
选项与参数:
cut主要的用途在于将同一行里面的数据进行分解,最常使用在分析一些数据或文字数据的时候。
cut是将一行信息当中,取出某部分我们想要的,而grep则是分析一行信息,若当中有我们所需要的信息,就将该行拿出来。
grep [-acinv] [--color=auto] '查找字符' filename
选项与参数:
补充:
last可以输出[账号/终端/来源/日期时间]的数据,并且是排列整齐的。
last | cut -d ' ' -f 1
能将每一行的第一个字符串输出来,很6,因为cut是按行处理的,而每一行数据又刚好由空格隔开,因此就能输出每行的第一个字符串
last | grep 'root'
将last中出现root的那些行取出来。
last | grep -v 'root
将last中没有root的那些行取出来。
last |grep 'root' |cut -d ' ' -f1
将last中所有有root的行取出来,并且只要第一列。
sort是很有趣的命令,它可以帮我们进行排序,而且可以根据不同的数据形式来排序。
sort [-fbMnrtuk] [file or stdin]
选项与参数:
-f : 忽略大小写的差异,例如A与a视为编码相同;
-b : 忽略最前面的空格字符部分;
-M : 以月份的名字来排序,例如JAN、DEC等的排序方法;
-n : 使用【纯数字】进行排序(默认是以文字形式来排序的);
-r : 反向排序;
-u : 就是uniq,相同的数据中,仅出现一行代表;
-t : 分割符号,默认是用[Tab]键来分割;
-k : 以哪个区间(filed)来进行排序的意思。
uniq
排序完成,将重复的数据仅列出一个显示。
uniq [-ic]
选项与参数:
-i : 忽略大小写字符的不同;
-c : 进行计数。
wc
计算输出信息的整体数据。
wc [-lwm]
选项与参数:
补充:
last可以输出[账号/终端/来源/日期时间]的数据,并且是排列整齐的。
last | cut -d ' ' -f1 |sort|uniq
将排序后的数据只取出一行来。
last | cut -d ' ' -f1|sort|uniq -c
统计出每行出现的次数(相当于group by加count)
tee会同时将数据流分送到文件与屏幕(screen),而输出到屏幕的,其实就是stdout,那就可以让下个命令继续处理。
tee [-a] file
选项与参数:
补充:
last可以输出[账号/终端/来源/日期时间]的数据,并且是排列整齐的。
last | tee last.list|cut -d " " -f1
tee是双重导向的分流命令,可以同时将数据流既送到文件屏幕一份,又保存到last.list文件中一份。
tr可以用来删除一段信息当中的文字,或是进行文字信息的替换。
tr [-ds] SET1 ...
选项与参数:
补充:
last可以输出[账号/终端/来源/日期时间]的数据,并且是排列整齐的。
last | tr [a-z] [A-Z]
将last输出的信息中的小写转换成大写。
使用[]可以设置一串字,也常常用来替换文件中的怪异符号。
col [-xb]
选项与参数:
虽然col有它特殊的用途,不过,很多时候,它可以用来简单地处理将[tab]按键替换成为空格键。
join看字面上的意义(加入/参加)就可以知道,它是在处理两个文件之间的数据,而且,主要是在处理【两个文件当中,有相同数据的那一行,才把它加在一起】的意思。
join [-ti12] file1 file2
选项与参数:
在使用join之前,你所需要处理的文件应该要事先经过排序(sort)处理。
paste就是直接将两行贴在一起,且中间以[Tab]键隔开。
paste [-d] file1 file2
选项与参数:
-d : 后面可以接分割字符,默认是以[Tab]来分隔;
expand
就是在将[Tab]按键转成空格键。
expand [-t] file
选项与参数:
split [-bl] file PREFIX
选项与参数:
xargs是在做什么?就以字面的意义来看,x是加减乘除的乘号,args则是arguments(参数)的意思。所以说,这个玩意儿就是在产生某个命令的参数的意思。
xargs [-0epn] command
选项与参数:
当xargs后面没有接任何的命令时,默认是以echo来输出。
要使用xargs的原因是,很多命令其实并不支持管道命令,因此我们可以通过xargs来提供该命令使用 标准输入。
在管道命令当中,常常会使用到前一个命令的stdout作为这次的stdin,某些命令需要用到文件名(例如tar)来进行处理时,该stdout与stdin可以利用减号"-"来替代。
简单来说,正则表达式(Regular Expression,或称为常规表示法)就是处理字符串的方法,它以行为单位来进行字符串的处理操作,正则表达式通过一些特殊符号的辅助,可以让用户轻易地完成【查找、删除、替换】某特定字符串的处理过程。
正则表达式基本上是一种【表示法】,只要程序支持这种表示法,那么该程序就可以用来作为正则表达式的字符串处理之用。
正则表达式的字符串表示方式依照不同的严谨度分为:基础正则表达式与扩展正则表达式。扩展正则表达式除了简单的一组字符串处理之外,还可以作群组的字符串处理。
对字符排序有影响的语系数据就会对正则表达式的结果有影响。
使用正则表达式时,需要特别留意当时环境的语系是什么,否则可能会发现与别人不相同的选取结果。
下面使用**【LANG=C】**这个语系来进行。
特殊符号 | 代表意义 |
[:alnum:] | 代表英文大小写字符及数字,亦即0-9、A~Z、a~z |
[:alpha:] | 代表任何英文大小写字符,亦即A~Z、a~z |
[:blank:] | 代表空格键与[Tab]按键两者 |
[:cntrl:] | 代表键盘上面 控制按键,包括CR、LF、Tab、Del等 |
[:digit:] | 代表数字而已,即0-9 |
[:graph:] | 除了空格符(空格键与[Tab]按键)外的其他所有按键 |
[:lower:] | 代表小写字符,即a~z |
[:print:] | 代表任何可以被打印出来的字符 |
[:punct:] | 代表标点符号(punctuation symbol),亦即:"'?!;:#$ |
[:upper:] | 代表大写字符,即A~Z |
[:space:] | 代表会产生空白的字符,包括空格键、[Tab]、CR等 |
[:xdigit:] | 代表十六进制的数字类型,因此包括0-9、A~F、a~f的数字字符 |
grep [-A] [-B] [--color=auto] '查找字符' filename
选项与参数:
grep最重要的功能就是进行字符串数据的比对,然后将符合用户需求的字符串打印出来。
grep在数据中查寻出一个字符串时,是以【整行】为单位来进行数据的选取。
在文件中查找tast或test字样的字符串:
grep -n 't[ae]st' filename
[]里面不论有几个字符,它都仅代表某【一个】字符。
行首^和行尾$:
那个^符号,在字符集合符号(括号[])之内与之外是不同的。在[]内代表反向选择。在[]之外则代表定位在行首的意义。
在正则表达式当中的【.】则代表【绝对有一个任意字符】的意思,这两个符号在正则表达式的意义如下:
想找出g后面接2到5个o,然后再接一个g的字符串:
grep -n 'go\{2,5\}g' filename
RE字符 | 意义与范例 |
^word | 意义:待查找的字符串(word)在行首 |
word$ | 意义:待查找的字符串(word)在行尾 |
. | 意义:代表【一定有一个任意字符】的字符 |
\ | 意义:转义符,将特殊符号的特殊意义去除 |
* | 意义:重复零个到无穷多个的前一个RE字符 |
[list] | 意义:字符集合的RE字符,里面列出想要选取的字符 |
[n1-n2] | 意义:字符集合的RE字符,里面列出想要选取的字符范围 |
[^list] | 意义:字符集合的RE字符,里面列出不要的字符串或范围 |
\{n,m\} | 意义:连续n到m个的【前一个RE字符】 意义:若为\{n\}则是连续n个的前一个RE字符 意义:若为\{n,\}则是连续n个以上的前一个RE字符 |
sed本身也是一个管道命令,可以分析标准输入。而且sed还可以将数据进行替换、删除、新增、选取特定行等功能。
sed [-nefr] [操作]
选项与参数:
操作说明(如sed ‘2,5d’,操作得用’ '包裹起来使用):[n1[,n2]]function
扩展正则表达式用grep -E或者是egrep(推荐)来表示。
RE字符 | 意义与范例 |
+ | 意义:重复【一个或一个以上】的前一个RE字符 |
? | 意义:【零个或一个】的前一个RE字符 |
| | 意义:用或(or)的方式找出数个字符串 |
( ) | 意义:找出【群组】字符串 |
( )+ | 意义:多个重复群组的判别 |
printf '打印格式' 实际内容
选项与参数:
关于格式方面有几个特殊的样式:
关于c语言程序内,常见的变量格式:
awk是一个非常棒的数据处理工具,相较于sed常常作用于一整个行的处理,awk则比较倾向于一行当中分成数个字段来处理。因此,awk相当于适合处理小型的文本数据。
awk '条件类型1{操作1} 条件类型1{操作1} ...' filename
awk可以处理后续接的文件,也可以读取来自前个命令的标准输出。
awk主要是处理每一行的字段内容的数据,而默认的字段的分隔符为"空格键"或"[Tab]键"。
具体例子看书pg379
取出第一列和第三列数据:
awk 'print $1 "\t" $3'
$0代表【一整列数据】
变量名称 | 代表意义 |
NF | 每一行($0)拥有的字段总数 |
NR | 目前awk所处理的是第几行数据 |
FS | 目前的分割字符,默认是空格键 |
运算单元 | 代表意义 |
> | 大于 |
< | 小于 |
>= | 大于或等于 |
<= | 小于或等于 |
== | 等于(基于判断) |
!= | 不等于 |
几个重要的事项先说明:
diff就是用在比对两个文件之间的差异,并且是以**行**为单位来比对,一般是用在ASCII纯文本文件的比对上。
diff通常是用在同一个文件(或软件)的新旧版本差异上。
diff [-bBi] from-file to-file
选项与参数:
- from-file : 一个文件名,作为原始比对文件的文件名;
- to-file : 一个文件名,作为目标比对文件的文件名;
注意,from-file或to-file可以用-替换,那个-代表【标准输入】之意。
- -b : 忽略一行当中,仅有多个空白的差异;
- -B : 忽略空白行的差异;
- -i : 忽略大小写的不同。
cmp主要也是比对两个文件,它主要利用**字节**为单位去比对,因此,当然也可以比对二进制文件。
cmp [-l] file1 file2
选项与参数:
- -l : 将所有不同点的字节处都列出来,因为cmp默认仅会输出第一个发现的不同点。
patch这个命令与diff可是有密不可分的关系。先比较新旧版本的差异,并将差异文件制作成为补丁文件,再由补丁文件更新旧文件即可。
一般来说,使用diff制作出来的比较文件通常使用扩展名为.patch。
patch -pN < patch_file <==更新
patch -R -pN < patch_file <==还原
选项与参数:
- -p : 后面可以接【取消几层目录】的意思;
- -R : 代表还原,将新的文件还原成原来旧的版本。
例子:想要打印 /etc/man_db.conf
pr /etc/man_db.conf
shell脚本(shell script,程序化脚本)是利用shell的功能写的一个【程序(program)】。这个程序是使用纯文本文件,将一些shell的语法与命令(含外部命令)写在里面。搭配正则表达式、管道命令与数据流重定向等功能,以达到我们所想要的处理目的。
shell脚本用在系统管理上面是很好的一项工具,但是用在处理大量数值运算上,就不够好了,原因在于shell脚本的速度较慢,且使用的CPU资源较多,会造成主机资源的分配不良。
在shell脚本的编写中还需要注意下面的事项:
执行shell文件,可以用如下方法:
编写第一个脚本:
(输入)mkdir bin;cd bin
bin==> vim hello.sh
(编辑脚本内容)
(#!/bin/bash)
#
#
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
exprot PATH
echo -e "Hello World! \a \n"
exit 0
养成良好的脚本编写习惯,在每个脚本的文件头处记录好:
包覆的内部程序代码最好能以[Tab]按键的空格向后推。
另外,编写脚本的工具最好使用vim而不是vi,因为vim会有额外的语法检验功能,能够在第一阶段编写时就发现语法方面的问题。
自己练习
利用【$((计算式))】来进行数值运算
重点在于【当子进程完成后,在子进程内的各项变量或操作将会结束而不会传回到父进程中】。
测试的参数 | 代表意义 |
1.关于某个文件名的【文件类型】判断,如test -e filename | |
-e | 该【文件名】是否存在(常用) |
-f | 该【文件名】是否存在且为文件(file)(常用) |
-d | 该【文件名】是否存在且为目录(dictionary)(常用) |
-b | 该【文件名】是否存在且为一个 block device 设备 |
-c | 该【文件名】是否存在且为一个 character device 设备 |
-S | 该【文件名】是否存在且为一个socket文件 |
-p | 该【文件名】是否存在且为一个FIFO(pipe)文件 |
-L | 该【文件名】是否存在且为一个链接文件 |
2.关于文件的权限检测,如test -r filename | |
-r | 检测该文件名是否存在且具有【可读】的权限 |
-w | 检测该文件名是否存在且具有【可写】的权限 |
-x | 检测该文件名是否存在且具有【可执行】的权限 |
-u | 检测该文件名是否存在且具有【SUID】的属性 |
-g | 检测该文件名是否存在且具有【SGID】的属性 |
-k | 检测该文件名是否存在且具有【Sticky bit】的属性 |
-s | 检测该文件名是否存在且为【非空文件】 |
3.两个文件之间的比较,如test file1 -nt file2 | |
-nt | (newer than)判断file1是否比file2新 |
-ot | (older than)判断file1是否比file2旧 |
-ef | 判断file1与file2是否为同一文件,可用在判断hard link的判定上。主要意义在判定,两个文件是否均指向同一个inode |
4.关于两个整数之间的判定,如test n1 -eq n2 | |
-eq | 两数值相等(equal) |
-ne | 两数值不等(not equal) |
-gt | n1大于n2(greater than) |
-lt | n1小于n2(less than) |
-ge | n1大于等于n2(greater than or equal) |
-le | n1小于等于n2(less than or equal) |
5.判定字符串的数据 | |
test -z string | 判定字符串是否为0?若string为空字符串,则为true |
test -n string | 判定字符串是否非为0?若string为空字符串,则为false。注:-n亦可忽略 |
test str1 == str2 | 判定str1是否等于str2,若相等,则返回true |
test str1 != str2 | 判定str1是否不等于str2,若相等,则返回false |
6.多重条件判定,例如:test -r filename -a -x filename | |
-a | (and)两条件同时成立。例如tset -r file -a -x file,则file同时具有r与x权限时,才返回true |
-o | (or)两条件任何一个成立。例如tset -r file -o -x file,则file同时具有r与x权限时,就可返回true |
! | 反相状态,如test ! -x file,当file不具有x时,返回true |
由于root在很多权限的限制上面都是无效的,所以使用root执行这个脚本时,常常会发现与ls -l观察到的结果并不相同。
还可以利用判断符号【[]】(就是中括号)来进行数据的判断。
注意:中括号两端需要有空格符来分割,比如: [ -z $() ]
比如:
/path/to/scriptname opt1 opt2 opt3 opt4
(第一列是$0,第二列是$1,以此类推)
注意:shift可以移动变量,而且shift后面可以接数字,代表拿掉前面几个参数的意思。
if [ 条件判断式 ];then
当条件判断式成立时,可以进行的命令工作内容;
fi <==将if反过来写,就成为fi,结束if的意思。
- && 代表AND
- || 代表OR
#一个条件判断,分成功执行与失败执行(else)
if [ 条件判断式 ];then
当条件判断式成立时,可以进行的命令工作内容;
else
当条件判断式不成立时,可以进行的命令工作内容;
fi <==将if反过来写,就成为fi,结束if的意思。
如果考虑更复杂的情况:
#多个条件判断,分多种不同情况执行(if...elif...elif...else)
if [ 条件判断式一 ];then
当条件判断式一成立时,可以进行的命令工作内容;
elif [ 条件判断式二 ];then
当条件判断式二成立时,可以进行的命令工作内容;
else
当条件判断式一与二均不成立时,可以进行的命令工作内容;
fi <==将if反过来写,就成为fi,结束if的意思。
学一个有趣的命令
这个命令可以查询到目前主机开启的网络服务端口(service ports),利用【netstat -tuln】来获取目前主机启动的服务。
几个常见的端口与相关网络服务的关系:
case $变量名称 in <==关键字是case,还有变量前有美元符号。
"第一个变量内容") <==每个变量内容建议用双引号括起来,关键字则为右圆括号。
程序段
;; <==每个内别结尾使用两个连续的分号来处理。
"第二个变量内容") <==每个变量内容建议用双引号括起来,关键字则为右圆括号。
程序段
;; <==每个内别结尾使用两个连续的分号来处理。
*) <==最后一个变量内容都会用*来代表所有其他值。
不包含第一个变量内容与第二个变量内容的其他程序执行段。
exit 1
;;
esac <==将case反过来写,就成为esac,结束case的意思。
一般来说,使用【case 变 量 i n 】 这 个 语 法 时 , 当 中 的 那 个 【 变量 in】这个语法时,当中的那个【 变量in】这个语法时,当中的那个【变量】大致有两种获取方法:
function fname(){
程序段
}
注意:因为shell脚本的执行方式是从上到下、从左到右,因此在shell脚本当中的function的设置一定要在程序的最前面。
function也是拥有内置变量的,它的内置变量与shell脚本很类似,函数名称代表示 $0 ,后续接的变量也是以 $1、$2…来替换的。
while [ condition ] <==中括号内的状态就是判断式
do <==do是循环的开始
程序段落
done <==done是循环的结束
while是【当condition条件成立时,就进行循环,直到condition的条件不成立才停止】
until [ condition ] <==中括号内的状态就是判断式
do <==do是循环的开始
程序段落
done <==done是循环的结束
until与while相反,它是【当condition条件成立时,就终止循环,否则就持续进行循环的程序段】
for这种语法,则是【已经知道要进行几次循环】的状态
for var in con1 con2 con3 ...
do
程序段
done
这个 $var 的变量内容在循环工作时:
$(seq 1 100) # seq为sequence(连续)的缩写之意
还可以使用 {1…100}来替换$(seq 1 100),都是从1到100连续取值的含义。
for (( 初始值;限制值;赋值运算 ))
do
程序段
done
for括号内的含义:
sh [-nvx] scripts.sh
选项与参数:
在输出信息中,在加号后面的数据其实都是命令串,由于sh -x的方式将命令执行过程也显示出来,这样用户就可以判断程序代码执行到哪一段时会出现相关的信息。
输入账号密码后,系统帮你处理了什么呢?
介绍两个结构:
每一行都代表一个账号,有几行就代表有几个账号在你的系统中。不过需要特别留意的是,里面很多账号本来就是系统正常运行所必须的,我们可以简称它为系统账号。
root:x:0:0:root:/root:/bin/bash
每一行都用【:】分格,一共七项,分别代表:
ID范围 | 该ID用户特性 |
0(系统管理员) | 当UID是0时,代表这个账号是【系统管理员】,所以当你要让其他的账号名称也具有root的权限时,将该账号的UID改为0即可。 |
1~999(系统账号) | 保留给系统使用的ID。 根据系统账号的由来,通常这类账号又大概被区分为两种: - 1-200:由Linux发行版自行建立的系统账号; - 201-999:若用户有系统账号需求时,可以使用的账号UID |
1000~60000(可登录账号) | 给一般用户使用。 |
第二个结构:
同样的,shadow每一行也都用【:】分格,一共九项,分别代表:
如果我忘记密码了,应该怎么办?
这个文件就是记录GID与组名的对应记录,每一行代表一个用户组,也是以【:】作为字段的分隔符,共分为四栏,分别代表:
关于有效任务组(effective group)与初始用户组(initial group)。GID就是初始用户组。
group
==> dmtsai wheel users
输出三个用户组,第一个输出的用户组即为有效用户组(effective group)。
newgrp
group
==> users wheel dmtsai
使用newgrp是有限制的,那就是你想要切换的用户组必须是你已经有支持的用户组。
这个文件内同样还是使用【:】来作为字段的分割字符,几乎与 /etc/group 一模一样。要注意的就是第二个字段,第二字段为密码栏,如果密码栏上面是【!】或为空时,表示该用户组不具有用户组管理员。
这四个字段意义是:
useradd [-u UID] [-g 初始用户组] [-G 次要用户组] [-mM]\
> [-c 说明栏] [-d 家目录绝对路径] [-s shell] 使用者账号名
注意: \ > 代表换行符。
选项与参数:
CentOS这些默认值主要会帮我们处理几个选项:
在 /etc/passwd 里面建立一行与账号相关的数据,包括建立 UID/GID/家目录等;
在 /etc/shadow 里面将此账号的密码相关参数写入,但是尚未有密码;
在 /etc/group 里面加入一个与账号名称一模一样的组名;
在 /home 下面建立一个与账号同名的目录作为用户家目录,且权限为700。
useradd参考文件
useradd -D
查看数据,这些数据其实是由 /etc/default/useradd 调用出来的。
UID/GID的密码参数在 /etc/login.defs 里面,文件的内容如下:
接下来处理用户密码。
passwd [--stdin] [账号名称] <==所有人均可使用来改自己的密码
passed [-l] [-u] [--stdin] [-S] [-n 日期] [-x 日期] [-w 日期] [-i 日期] 账号
<==上面这个是root功能
选项与参数:
点击跳转