- 文件的属性以及权限
- 文件的属性(ls-l)
- 文件的类型以及权限
- 修改文件属性
- chgrp :改变文件所属群组。注意!!!只有root权限才有求权限使用此命令
chgrp [-R] group_name dirname/filename
-R : 进行递归(recursive)的持续变更
- chown :改变文件拥有者注意!!!只有root权限才有求权限使用此命令
chown [-R] owner_name dirname/filename(只修改拥有者)
chown [-R] owner_name:group_name dirname/filename(修改拥有者和所属群组)
- chmod:改变权限
1、chmod [-R] xyz dirname/filename
e.g.chmod 777 .bashrc
2、
e.g.
a)chmod u=rwx,go=rx .bashrc
b)chmod a-x .bashrc
c)chmod a+w .bashrc
- touch(修改文件时间或创建新文件)
touch [-option] 文件
-a :仅修订 access time;????(好像可以修改ctime)
-c :仅修改文件的时间,若该文件不存在则不建立新文件;
-d :后面可以接欲修订的日期而不用目前的日期,也可以使用 --date="日期或时间"
-m :仅修改 mtime ;
-t :后面可以接欲修订的时间而不用目前的时间,格式为[YYYYMMDDhhmm]e.g.
a)touch test(atime/ctime为当前时间)
b)touch -d "2 days ago" bashrc(atiome/mtime都改变)(无法改变ctime)
c)touch -t 201406150202 bashrc(atiome/mtime都改变)(无法改变ctime)
- 修改文件默认权限
- umask-指定『目前用户在建立文件或目录时候的权限默认值』
e.g.
a)umask -终端回复0022 -指的是『该默认值需要减掉的权限!』
b)umask -S -终端回复u=rwx,g=rx,o=rx
c)umask 022 (修改文件的默认权限为022)
- 修改文件的隐藏属性
- chattr(配置文件的隐藏属性)
chattr [+-=][ASacdistu] 文件或目录名称
a :当设定 a 之后,这个文件将只能增加数据,而不能删除也不能修改数据,只有 root 才能设定这属性
i :当设定i之后,这个文件『不能被删除、改名、设定连结也无法写入或新增数据!』对于系统安全性有相当大的帮助!只有 root 能设定此属性
e.g.
a)chattr +i test
- lsattr(显示文件隐藏属性)
lsattr [-option] 文件或目录
-a :将隐藏文件的属性也秀出来;
-d :如果接的是目录,仅列出目录本身的属性而非目录内的文件名;
-R :连同子目录的数据也一并列出来!
- 文件特殊权限
- SUID-(仅可用在二进制程序,不可用在shell脚本以及目录,因为要执行呢!)- -rwsr-xr-x
- SGID - -rwx--s--x
1、当SGID对于二进制文件来说的时候
2、当SGID对于目录来说的时候
- SBIT-只针对目录有效 - drwxrwxrwt
- chmod
chmod 4755 filename(设置了SUID)
- 相对路径
1、.代表当前的目录
2、..代表上一层目录
3、-代表前一个工作目录
4、~代表目前使用者身份所在的家目录
- 目录相关操作
- cd(Change Directory)-切换工作目录
e.g.cd ./test(cd = cd ~)
- pwd(print work directory)-显示当前目录绝对路径
- mkdir(Make Directory)-建立目录
-m:配置文件案的权限
-p:递归建立包含子目录的目录
e.g.
1、mkdir test
2、mkdir -p test1/test2/test3/test4
3、mkdir -m 711 test2
- rmdir(Remove Directory)-删除空目录(切记是空目录!)
-p:递归删除包含子目录的目录(子目录要为空目录)
- $PATH
当我们在执行一个指令的时候,举例来说『ls』好了,系统会依照 PATH 的设定去每个 PATH 定义的
目录下搜寻文件名为 ls 的可执行文件, 如果在 PATH 定义的目录中含有多个文件名为 ls 的可执行文
件,那么先搜寻到的同名指令先被执行!
- 文件与目录管理
- ls(list)-文件目录与查看
-a :全部的文件,连同隐藏档( 开头为 . 的文件) 一起列出来(常用)
-d :仅列出目录本身,而不是列出目录内的文件数据(常用)
-l :长数据串行出,包含文件的属性与权限等等数据;(常用)-ll
-i :列出 inode 号码
-S :以文件容量大小排序,而不是用档名排序;
- cp(Copy)-复制文件或目录
cp [option] src des
cp [option] src1 src2 src3 dir_des
-a :副之后的文件特性与源文件一模一样
-i :若目标文件(destination)已经存在时,在覆盖时会先询问动作的进行(常用)
-r :递归持续复制,用于目录的复制行为;(常用)
-l :进行硬式连结(hard link)的连结档建立,而非复制文件本身;
-s :复制成为符号链接文件 (symbolic link),亦即『快捷方式』文件;
- rm(Remove)-删除文件或目录
rm [-fir] 文件或目录
-f :就是 force 的意思,忽略不存在的文件,不会出现警告讯息;
-i :互动模式,在删除前会询问使用者是否动作
-r :递归删除啊!最常用在目录的删除了!这是非常危险的选项!!!
- mv(Move)-移动文件与目录
mv [-fiu] source destination
-f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;
-i :若目标文件 (destination) 已经存在时,就会询问是否覆盖!
-u :若目标文件已经存在,且 source 比较新,才会更新 (update)
- 文件内容的查看
- cat(Concatenate)-由第一行开始显示文件内容(缺点:全部显示,太多)
-b :列出行号,仅针对非空白行做行号显示,空白行不标行号!
-n :打印出行号,连同空白行也会有行号,与 -b 的选项不同;
- tac(cat逆置)-由最后一行反向显示文件内容,与cat相反(缺点:全部显示,太多)
- nl(Number of Lines)-显示行号(对行号做比较多的显示设计)
-b:指定行号指定的方式,主要有两种:
-b a :表示不论是否为空行,也同样列出行号(类似 cat -n);
-b t :如果有空行,空的那一行不要列出行号(默认值);
-n:列出行号表示的方法,主要有三种:
-n ln :行号在屏幕的最左方显示;
-n rn :行号在自己字段的最右方显示,且不加 0 ;
-n rz :行号在自己字段的最右方显示,且加 0 ;
-w:行号字段的占用的字符数。
- more-可翻页查看
/字符串-重复前一个查找
- less-比more更好
- head-列出前面几行
head [-n number] 文件
-n:后面接数字,代表显示几行的意思(若为正数则是显示文件的前面num行,若是负数则是除了文件的倒数num不显示,其余显示)。
- tail-列出最后几行
tail [-n number] 文件
tail -n +100 /etc/man_db.conf 代表该文件从 100 行以后都会被列出来
tail -n 20 /etc/man_db.conf 显示最后的 20 行
- 查找文件与命令
- file -(观察文件类型)
- which-(脚本文件的查找)
-a :将所有由 PATH 目录中可以找到的指令均列出,而不止第一个被找到的指令名称
这个指令是根据『PATH』这个环境变量所规范的路径,去搜寻『执行档』的档名
- whereis -(由一些特定的目录中寻找文件文件名)
-l :可以列出 whereis 会去查询的几个主要目录而已
- locate -(寻找的数据是由『已建立的数据库 /var/lib/mlocate/』 里面的数据所搜寻到的)
限制:他是经由数据库来搜寻的,而数据库的建立默认是在每天执行一次,所以当你新建立起来的文件, 却还在数据库更新之前搜寻该文件,那么 locate 会告诉你『找不到!』!因为必须要更新数据库呀!(updatedb)
- find -(强大)
find [PATH] [option] [action]
1、关于查找文件时间
-mtime n :n 为数字,意义为在 n 天之前的『一天之内』被更动过内容的文件;
-mtime +n :列出在 n 天之前(不含 n 天本身)被更动过内容的文件档名;
-mtime -n :列出在 n 天之内(含 n 天本身)被更动过内容的文件档名。
-newer file :file 为一个存在的文件,列出比 file 还要新的文件档名
2、关于查找文件user/group
-user name :name 为使用者账号名称喔!例如 dmtsai
-group name:name 为组名喔,例如 users ;
-nouser :寻找文件的拥有者不存在 /etc/passwd 的人!
-nogroup :寻找文件的拥有群组不存在于 /etc/group 的文件!
3、关于查找文件name以及权限-name filename:搜寻文件名为 filename 的文件;
-size [+-]SIZE:搜寻比 SIZE 还要大(+)或小(-)的文件。这个 SIZE 的规格有:c: 代表 byte, k: 代表 1024bytes。所以,要找比 50KB
还要大的文件,就是『 -size +50k 』
-type TYPE:搜寻文件的类型为 TYPE 的,类型主要有:一般正规文件 (f), 装置文件 (b, c),目录 (d), 连结档 (l), socket (s), 及 FIFO (p) 等属性。
-perm mode:搜寻文件权限『刚好等于』 mode 的文件,这个 mode 为类似 chmod的属性值,举例来说, -rwsr-xr-x 的属性为 4755 !
-perm -mode (比它大):搜寻文件权限『必须要全部囊括 mode 的权限』的文件,举例来说,我们要搜寻 -rwxr--r-- ,亦即 0744 的文件,使用-perm -0744,当一个文件的权限为 -rwsr-xr-x ,亦即 4755 时,也会被列出来,
因为 -rwsr-xr-x 的属性已经囊括了 -rwxr--r-- 的属性了。
-perm /mode(比它小,通常用于特殊权限的查找):搜寻文件权限『包含任一 mode 的权限』的文件,举例来说,我们搜寻-rwxr-xr-x ,亦即 -perm /755 时,但一个文件属性为 -rw-------也会被列出来,因为他有 -rw.... 的属性存在!
- 文件系统特性
- superblock/inode/block含义
- block限制
- inode记录内容
- superblock内容
- 目录树内容
1、文件系统会分配一个 inode 与至少一块 block 给该目录。其中, inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码; 而 block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据。也就是说目录所占用的 block 内容在记录如下的信息:
2、目录树读取顺序
因为文件名是记录在目录的 block 当中, 因此当我们要读取某个文件时,就务必会经过目录的 inode 与 block ,然后才能够找到那个待读取文件的 inode 号码,最终才会读到正确的文件的 block 内的数据。
e.g.
读取/etc/passwd的内容
通过挂载点读取根目录的inode->根目录的inode对于我们的权限是r,x->根据根目录的inode找到根目录的区块->在区块中找到内容有etc/目录的inode->etc的inode对于我们的权限是r,x->根据etc的inode找到etc区块->在区块中找到内容有passwd文件的inode->判断inode对于我们的权限是r->读取passwd。
- 目录树新增文件顺序
1. 先确定用户对于欲新增文件的目录是否具有 w 与 x 的权限,若有的话才能新增;
2. 根据 inode bitmap 找到没有使用的 inode 号码,并将新文件的权限/属性写入;
3. 根据 block bitmap 找到没有使用中的 block 号码,并将实际的数据写入 block 中,且更新 inode 的 block指向数据;
4. 更新元数据:将刚刚写入的 inode 与 block 数据同步更新 inode bitmap 与 block bitmap,并更新 superblock 的内容。
- ext2文件系统对于数据不一致状态的处理(非常费时)
数据不一致状态:你的文件在写入文件系统时,因为不知名原因导致系统中断(例如突然的停电啊、 系统核心发生错误啊~等等的怪事发生时),所以写入的数据仅有 inode table 及 data block 而已, 最后一个同步更新元数据的步骤并没有做完,此时就会发生 metadata 的内容与实际数据存放区产生不一致(Inconsistent) 的情况了。
在早期的 Ext2 文件系统中,如果发生这个问题, 那么系统在重新启动的时候,就会藉由 Superblock 当中记录的 valid bit (是否有挂载) 与 filesystem state (clean 与否)等状态来判断是否强制进行数据一致性的检查!
- 日志式文件系统 (Journaling filesystem)对于数据不一致状态的处理(多规划出日志记录区)
1. 预备:当系统要写入一个文件时,会先在日志记录区块中纪录某个文件准备要写入的信息;
2. 实际写入:开始写入文件的权限与数据;开始更新 metadata 的数据;
3. 结束:完成数据与 metadata 的更新后,在日志记录区块当中完成该文件的纪录。
- 异步处理
当系统加载一个文件到内存后,如果该文件没有被更动过,则在内存区段的文件数据会被设定为干净(clean)的。 但如果内存中的文件数据被更改过了(例如你用 nano 去编辑过这个文件),此时该内存中的数据会被设定为脏的 (Dirty)。此时所有的动作都还在内存中执行,并没有写入到磁盘中! 系统会不定时的将内存中设定为『Dirty』的数据写回磁盘,以保持磁盘与内存数据的一致性。 你也可以利用第四章谈到的 sync 指令来手动强迫写入磁盘。若正常关机时,关机指令会主动呼叫 sync 来将内存的数据回写入磁盘内;但若不正常关机(如跳电、当机或其他不明原因),由于数据尚未回写到磁盘内, 因此重新启动后可能会花很多时间在进行磁盘检验,甚至可能导致文件系统的损毁(非磁盘损毁)。
- 挂载 -将文件系统与目录树结合的动作我们称为『挂载』
挂载点一定是目录,该目录为进入该文件系统的入口。
- 文件系统简单操作
- df(Disk free) -文件系统的整体磁盘使用量
-h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
-i :不用磁盘容量,而以 inode 的数量来显示
在 df 后面加上目录或者是文件时, df会自动的分析该目录或文件所在的文件系统,并将该文件系统的信息显示出来。
- du(Disk usage) -文件系统磁盘使用量或文件占了多少容量
-s :列出总量而已,而不列出每个各别的目录占用容量;
-k :以 KBytes 列出容量显示;
-m :以 MBytes 列出容量显示;
- 硬连接与符号连接
ln /root/test /tmp/test_hard
1、硬链接不会建立新的 inode 信息,也不会更改 inode 的总数。
2、硬链接不能跨文件系统(分区)建立,因为在不同的文件系统中,inode 号是重新计算的。
3、硬链接不能链接目录
4、不论是修改源文件(test 文件),还是修改硬链接文件(test-hard 文件),另一个文件中的数据都会发生改变。
5、不论是删除源文件,还是删除硬链接文件,只要还有一个文件存在,这个文件(inode 号是 262147 的文件)都可以被访问。
- 软连接
个人感觉上图出错了,因为软连接会新建自己的 inode 信息和 block,只是在 block 中不存储实际文件数据,而存储的是源文件的文件名及 inode 号,因此我觉得check_soft的指向应该为指向/,根据名字一步步的指向/root,直到/root/check,不然的话你仍然直接指向check,删除了源文件又有什么影响呢,我仍然有多一个inode指向它。同时另一个有力证据时软连接必须连接的是绝对位置而不能是相对位置,这也很好的说明了软连接是依靠位置来一步步找到指向的连接的。
1、不论是修改源文件(check),还是修改硬链接文件(check-soft),另一个文件中的数据都会发生改变。因为你通过软连接进入此目录或者打开此文件,都意味着操作源文件。
2、删除软链接文件,源文件不受影响。而删除原文件,软链接文件将找不到实际的数据,从而显示文件不存在。
3、软链接会新建自己的 inode 信息和 block,只是在 block 中不存储实际文件数据,而存储的是源文件的文件名及 inode 号。
4、软链接可以链接目录。
5、软链接可以跨分区,因为是根据绝对位置以及inode。
- 磁盘操作
- lsblk -(List block device)-列出所有的存储设备以及基本信息(容量、只读、类型等)
- blkid -列出设备的UUID(全局唯一标志符(universally unique identifier))
- parted -列出分区表类型
- gdisk/fdisk -对分区进行操作,例如新增删除 -『MBR 分区表请使用 fdisk 分区, GPT 分区表请使用 gdisk 分区!』
- partprobe -更新linux内核的分区表信息
- mkfs -(make filesystem)-创建文件系统,也就是磁盘格式化,设置容量,inode有关设置等
- 挂载与卸载
挂载点是目录, 而这个目录是进入磁盘分区槽(其实是文件系统啦!)的入口
part
简单归纳上图:
1、文件系统与目录的关系应该是一对一的关系。
2、挂载的目录为非空目录时,原先在非空目录下的文集爱你就会暂时的被隐藏掉了!注意喔!并不是被覆盖掉, 而是暂时的隐藏了起来,等到新分区槽被卸除之后,则非空目录下原本的内容就会再次的跑出来啦!因为挂载即意味着此目录与文件系统的inode相同,即此目录即为文件系统,因此会暂时找不到此目录下的文件。
1、mount
mount [-t 文件系统] UUID='' 挂载点
[root@study ~]# mount [-t 文件系统] 文件系统名 挂载点mount --bind /var /data/var 利用 mount 来将某个目录挂载到另外一个目录去喔!这并不是挂载文件系统,而是额外挂载某个目录的方法,也可以用符号连接。
2、umount [-fn] 装置文件名或挂载点
-f :强制卸除!可用在类似网络文件系统 (NFS) 无法读取到的情况下;
-l :立刻卸除文件系统,比 -f 还强!
- 设置启动挂载
/etc/fstab(filesystem table):系统开机时会主动读取/etc/fstab这个文件中的内容,根据文件里面的配置挂载磁盘。这样我们只需要将磁盘的挂载信息写入这个文件中我们就不需要每次开机启动之后手动进行挂载了。
填入格式:<file system>-<mount point>-<type>-<options>-<dump>-<pass>
磁盘装置文件名-挂载点-磁盘分区槽的文件系统格式(xfs, ext4等)-文件系统参数(defaults)-能否被 dump 备份指令作用-是否以 fsck 检验扇区
- 基本概念
- 什么是操作系统?什么是内核?
总的说来,一个操作系统包含了内核(是一个提供硬件抽象层、磁盘及文件系统控制、多任务等功能的系统软件)以及其他计算机系统所必须的组件(如函数库、编译器、调式工具、文本编辑器、网站服务器,以及一个Unix的使用者接口(Unix shell)等,这些都是操作系统的一部分,而且每一个模块如编译器都是一个单独的进程,运行在操作系统中)。所以一个内核不是一套完整的操作系统。(https://blog.youkuaiyun.com/qq_26849233/article/details/74527779)
- 什么是shell?什么是Bash?
shell是用户和Linux(或者更准确的说,是用户和Linux内核)之间的接口程序。你在提示符下输入的每个命令都由shell先解释然后传给Linux内核。shell 是一个命令语言解释器(command-language interpreter)。拥有自己内建的 shell 命令集。此外,shell也能被系统中其他有效的Linux 实用程序和应用程序(utilities and application programs)所调用。
Bash全名是Bourne Again shell,说明Bash也是一种shell,由于其功能十分强大,因此Linux将其作为了自己的默认shell。
- BASH
- type -指令是来自于外部指令(指的是其他非 bash 所提供的指令) 或是内建在 bash 当中的呢?
-t :当加入 -t 参数时,type 会将 name 以底下这些字眼显示出他的意义:
file :表示为外部指令;
alias :表示该指令为命令别名所设定的名称;
builtin :表示该指令为 bash 内建的指令功能;
- 终端操作
1、\转意字符:利用『 \[Enter] 』来将 [Enter] 这个按键『跳脱!』,让Enter不再是执行的意思,而是换行
2、快速组合键
- 变量的操作
1、echo -显示变量内容
2、变量赋值:变量=变量内容
3、变量内容若有空格符可使用双引号『"』或单引号『'』将变量内容结合起来,但
a)双引号内的特殊字符如 $ 等,可以保有原本的特性(变量仍然是变量),如下所示:『var="lang is $LANG"』则『echo $var』可得『lang is zh_TW.UTF-8』
b)单引号内的特殊字符则仅为一般字符 ((变量为纯文本),如下所示:『var='lang is $LANG'』则『echo $var』可得『lang is $LANG』
4、可用转义符号『 \ 』将特殊符号(如 [Enter], $, \, 空格符, '等)变成一般字符,如:『myname=VBird\ Tsai』
5、$() -先执行括号里面的内容 ${PATH} -等同于“PATH”
6、若该变量为扩增变量内容时,则可用 "$变量名称" 或 ${变量} 累加内容,如下所示:『PATH="$PATH":/home/bin』或『PATH=${PATH}:/home/bin』
7、export -设置环境变量(作用域仅在当前shell脚本下.,切换到另一个终端就会失效)
8、unset -取消变量的方法
9、${varible} -将变量封闭起来,类似于C的(),最好习惯这种写法,不要直接$varible,防止编译器误解。
- 环境变量(作用域仅在当前shell脚本下[包括子进程].,切换到另一个终端就会失效)
1、env -environment 列出目前shell环境下的所有环境变量
2、set -观察所有变量 (含环境变量与自定义变量)
3、重要的环境变量:
a)$ -『目前这个 Shell 的进程号』 -echo $$ (显示目前shell的PID-Process ID)
b)? -(关于上个执行指令的回传值,成功执行返回0,执行出错,返回错误代码,非0。 -echo $?
4、export -自定义变量转成环境变量
- 变量读取
1、read -读取来自键盘输入的变量
read [-pt] variable
-p :后面可以接提示字符!
-t :后面可以接等待的『秒数!』 几秒之内没有任何动作时, 该指令就会自动略过了
- 变量删除
# :符合取代文字的『最短的』那一个;(从前面到后面)
##:符合取代文字的『最长的』那一个(从前面到后面)echo ${path#/*:}(从/到:)
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/binecho ${path##/*:}(从/到:)
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin% :符合取代文字的『最短的』那一个;(从后面到前面)
%%:符合取代文字的『最长的』那一个(从后面到前面)echo ${path%:*bin}(从bin到:)
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin
:/home/dmtsai/binecho ${path%%:*bin}(从bin到:)
/usr/local/bin
:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
- 变量替换
echo ${path/sbin/SBIN} -若变量内容符合『sbin』则『第一个sbin会被SBIN取代』
echo ${path//sbin/SBIN} -若变量内容符合『sbin』则『全部sbin会被SBIN取代』
- 变量测试与内容替换
先记住1,2,而后3,4是1,2的反转,5,6跟1,2是一样规律的。:这个符号就是将str是空字符当成是无符号。7,8若str是空,则输出错误信息,之后通过$?来判断。
- 命令别名设置
- alias
alias 『别名』='指令 选项...' -单单输入alias查看所有别名
e.g.
1、alias rm='rm -i'
- declare
declare [-aixr] variable
-a :将后面名为 variable 的变量定义成为数组 (array) 类型
-i :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
-x :用法与 export 一样,就是将后面的 variable 变成环境变量;
-r :将变量设定成为 readonly 类型,该变量不可被更改内容,也不能 unset,常量
- 通配符
- 数据流重定向 -数据给他定向到其他地方去
- 输出注意事项
- /dev/null 垃圾桶黑洞设备
- find /home -name .bashrc 1> list 2>&1 -正确与错误数据通通写入同一个文件去
- 输入
1、cat > catfile < ~/.bashrc -用cat去建立一个新文件catfile,但文件内容由bashrc输入
2、<< 这个连续两个小于的符号了。 他代表的是『结束的输入字符』
cat > catfile << "eof"
> This is a test.(>起作用)
> OK now stop(>起作用)
> eof <==输入这关键词,立刻就结束而不需要输入 [ctrl]+d
- 命令执行判断根据
ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe -建立 /tmp/abc/hehe 这个文件, 但我并不知道 /tmp/abc 是否存在
ls /tmp/vbirding && echo "exist" || echo "not exist" -ls 测试 /tmp/vbirding 是否存在,若存在则显示 "exist" ,若不存在,则显示 "not exist"!
ls /tmp/vbirding || echo "not exist" && echo "exist" -出错
- 管道命令 -| (管线命令『 | 』仅能处理经由前面一个指令传来的正确信息)
- cut
选项与参数:
-d :后面接分隔字符。与 -f 一起使用;
-f :依据 -d 的分隔字符将一段讯息分区成为数段,用 -f 取出第几段的意思;
-c :以字符 (characters) 的单位取出固定字符区间;echo ${PATH} | cut -d ':' -f 5 -取变量PATH的内容,以:为分隔符,取第五个
/usr/local/bin:/usr/bin : /usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
export | cut -c 12- (注意有个“-”,倘若想要取12-15的字符,则要12-15)
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/home/dmtsai"
declare -x HOSTNAME="study.centos.vbird"HISTCONTROL="ignoredups"
HISTSIZE="1000"
HOME="/home/dmtsai"
HOSTNAME="study.centos.vbird"
- grep
-c :计算找到 '搜寻字符串' 的次数 (count:仅输出一个数字)
-i :忽略大小写的不同,所以大小写视为相同 (ingore)
-n :顺便输出行号
-v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!
- sort (排序)
-f :忽略大小写的差异,例如 A 与 a 视为编码相同;
-n :使用『纯数字』进行排序(默认是以文字型态来排序的);
-r :反向排序;
-u :就是 uniq ,相同的数据中,仅出现一行代表;
-t :分隔符,预设是用 [tab] 键来分隔;
-k :以那个区间 (field) 来进行排序的意思cat /etc/passwd | sort -t ':' -k 3 -n 读取到passwd,以 : 来分隔的,第三栏来进行数字排序
- uniq -重复的资料仅列出一个显示
-i :忽略大小写字符的不同;
-c :进行计数last | cut -d ' ' -f1 | sort | uniq -c
1
6 (unknown
47 dmtsai
4 reboot
7 root
1 wtmp
- wc -(Word Count)-这个文件里面有多少字?多少行?多少字符
-l :仅列出行;
-w :仅列出多少字(英文单字);
-m :多少字符;cat /etc/man_db.conf | wc
131 723 5171
# 输出的三个数字中,分别代表: 『行、字数、字符数』
- tee -(T (T形水管接口)) -双重定向-将数据流分送到文件去与屏幕 (screen)
last | tee last.list | cut -d " " -f1 将 ls 的数据存一份到 ~/homefile ,同时屏幕也有输出讯息,继续用管道命令处理
- tr -traslate
last | tr '[a-z]' '[A-Z]' -所有的小写变成大写字符
- expand -将 [tab] 按键转成空格键 grep '^MANPATH' /etc/man_db.conf | expand -t 6 - |
- col -x:将 tab 键转换成对等的空格键
- split -将一个大文件,依据文件大小或行数来分区,就可以将大文件分区成为小文件了
split [-bl] file PREFIX
-b :后面可接欲分区成的文件大小,可加单位,例如 b, k, m 等;
-l :以行数来进行分区。
PREFIX :代表前导符的意思,可作为分区文件的前导文字。split -b 300k /etc/services services
ls -al / | split -l 10 - lsroot (由于是用管道,因此用-代表stdout)
- 正则表达式
- 什么是正规表达式?
正规表示法就是处理字符串的方法,他是以行为单位来进行字符串的处理行为, 正规表示法透过一些特殊符号的辅助,可以让使用者轻易的达到『搜寻/删除/取代』某特定字符串的处理程序!大多数程序都支持正则表达式。
- 正规表达式与通配符的关系
https://www.cnblogs.com/xiongyunqi/p/3735846.html必看!!
『正规表示法与通配符是完全不一样的东西!』 这很重要喔!因为『通配符 (wildcard) 代表的是 bash 操作接口的一个功能』,但正规表示法则是一种字符串处理的表示方式!
通配符一般用于文件名,而正则表达式多用于字符串。
- 基础正则表达式
[:alnum:] 代表英文大小写字符及数字,亦即 0-9, A-Z, a-z (alpha+num)
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 代表小写字符,亦即 a-z
[:upper:] 代表大写字符,亦即 A-Z
[:digit:] 代表数字而已,亦即 0-9
- grep -高级选项(配合正则表达式) -说出下面式子的意思
- grep -vin 'the' regular_express.txt ——找出文件中不含the的行,忽略大小写并打印行号(the、ThE均可找到)
- grep -n 't[ae]st' regular_express.txt ——tast、test、
taest(wrong)- grep -n '[^g]oo' regular_express.txt ——我需要的是 oo ,但是 oo 前面不能是 g 就是了
- grep -n '[^a-z]oo' regular_express.txt = grep -n '[^[:lower:]]oo' regular_express.txt ——oo前不是小写字母
- grep -n '^[[:lower:]]oo' regular_express.txt ——开头是小写字母
- grep -n '^the' regular_express.txt ——行首是the的行,注意与3、4的非区分
- grep -n '^[a-z]' regular_express.txt ——行首是小写字母
- 竟然说明是行首,因此我这个符号就要在最外面^,不能被任何符号抢占了我最外面的地位。
- grep -n '^[^a-zA-Z]' regular_express.txt ——非字母加开头=开头非字母
- grep -n '\.$' regular_express.txt ——结尾是.的,\转移字符
- grep -n '^$' regular_express.txt ——空行(开头之后就到结尾了)
- . (小数点):代表『一定有一个任意字符』的意思;
* (星星号):代表『重复前一个字符, 0 到无穷多次』的意思,为组合形态- grep -n 'g..d' regular_express.txt ——强调 g 与 d 之间一定要存在两个字符
- grep -n 'ooo*' regular_express.txt ——o两个及以上
- grep -n 'g*g' regular_express.txt ——该行当中拥有一个以上的 g
- grep -n 'g.*g' regular_express.txt ——.* 就代表零个或多个任意字符/代表 g 开头与 g 结尾,中间任意字符均可接受
- 限定范围的字符 {} 了。 但因为 { 与 } 的符号在 shell 是有特殊意义的,因此, 我们必须要使用跳脱字符 \ 来让他失去特殊意义才行。
- grep -n 'o\{2\}' regular_express.txt ——找到两个 o 的字符串,但由于可能会存在oooo的情况,这是因为在oooo里也找到了oo
- grep -n 'go\{2,5\}g' regular_express.txt ——g 后面接 2 到 5 个 o
- grep -n 'go\{2,\}g' regular_express.txt ——开始和结束字符都是g,但o是两个及以上
- 扩展正则表达式 ——egrep
- 注意!!!:『正规表示法的特殊字符』与一般在指令列输入指令的『通配符』并不相同, 例如,在通配符当中的 * 代表的是『 0 ~ 无限多个字符』的意思,但是在正规表示法当中, * 则是『重复 0到无穷多个的前一个 RE 字符』的意思~使用的意义并不相同,不filename=${fileuser:-"filename"}要搞混了!通配符中的*与正则表达式中的.*一样意思。
- sed(Stream EDitor) ——处理文本中一行的数据,将数据进行取代、删除、新增、撷取特定行等等的功能
- sed [-nefr] [动作]
选项与参数:
-n:使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到屏幕上。但如果加上 -n 参数后,则只有经过 sed 特殊处理的那一行(或者动作)才会被列出来。
-i :直接修改读取的文件内容,而不是由屏幕输出。
动作说明:[n1[,n2]]function n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』
function 有底下这些咚咚:
a :新增, a 的后面可以接字符串,而这些字符串会在新的一行出现(目前的下一行)~ add
c :取代, c 的后面可以接字符串,这些字符串可以取代 n1,n2 之间的行! change——改变行
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚; delete
i :插入, i 的后面可以接字符串,而这些字符串会在新的一行出现(目前的上一行); insert
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运作~ print
s :取代,可以直接替换字符的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦! ——改变字符
- nl /etc/passwd | sed '2,5d'
- nl /etc/passwd | sed '2a drink tea'
- nl /etc/passwd | sed '2a Drink tea or ......\(Enter)> drink beer ?' ——在\的后面加上回车键,就可以在2的下一行插入\之前的内容,在下一行插入\之后的内容。
- nl /etc/passwd | sed '2,5c No 2-5 number' ——将2-5行替换成一行的字符
- nl /etc/passwd | sed -n '5,7p' ——查看5-7行的内容
- sed 's/要被取代的字符串/新的字符串/g'
- ……| sed 's/^.*inet //g' | sed 's/ *netmask.*$//g' ——前面的……是指某些指令,之后用sed将^.*inet 替换为空(正则表达式),此后也是一样道理
- sed -i 's/\.$/\!/g' regular_express.txt ——直接修改文件内容,注意转义符\
- printf ——格式化处理
- printf '打印格式' 实际内容
- printf '%s\t %s\t %s\t %s\t %s\t \n' $(cat printf.txt) ——由于printf不支持管道,因此先用$()先执行实际内容
%s 代表一个不固定长度的字符串,而字符串与字符串中间就以 \t 这个 [tab] 分隔符来处理!
- printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt | grep -v Name)
上面的格式共分为五个字段, %10s代表的是一个长度为 10 个字符的字符串字段,%5i 代表的是长度为 5 个字符的数字字段,至于那个 %8.2f 则代表长度为 8 个字符的具有小数点的字段,其中小数点有两个字符宽度,小数点本身 (.) 占一位。
- awk ——"Aho Weiberger and Kernighan" 三个作者的姓的第一个字母 ——比较倾向于一行当中分成数个『字段』来处理
awk '条件类型 1{动作 1} 条件类型 2{动作 2} ...' filename
last -n 5 | awk '{print $1 "\t" $3}' ——$0 代表『一整列资料』的意思
last -n 5| awk '{print $1 "\t lines: " NR "\t columns: " NF}'
cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}'
- shell脚本
- 什么是shell脚本
shell script 是利用 shell 的功能所写的一个『程序 (program)』,这个程序是使用纯文本文件,将一些 shell 的语法与指令(含外部指令)写在里面, 搭配正规表示法、管线命令与数据流重导向等功能,以达到我们所想要的处理目的。
shell script 就像是早期 DOS 年代的批处理文件 (.bat) ,最简单的功能就是将许多指令汇整写在一起, 让使用者很轻易的就能够 one touch 的方法去处理复杂的动作 (执行一个文件 "shell script" ,就能够一次执行多个指令)。
- 脚本规范
#!/bin/bash
# Program:
#This program shows "Hello World!" in your screen.
# History:
# 2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Hello World! \a \n"
exit 01、第一行 #!/bin/bash 在宣告这个 script 使用的 shell 名称:
2、主要环境变量的宣告:
3、主要程序部分
4、执行成果告知 (定义回传值)
- 数值运算:简单的加减乘除
total=$((${firstnu}*${secnu})) ——记得用括号
- script 的执行方式差异
1、直接执行
a)绝对路径
b)相对路径
c)将文件路径定义在${PATH}
2、利用bash (或 sh) 来下达脚本
该 script 都会使用一个新的 bash 环境来执行脚本内的指令!也就是说,使用这种执行方式时, 其实 script 是在子程序的 bash 内执行的!『当子程序完成后,在子程序内的各项变量或动作将会结束而不会传回到父程序中』!
3、使用 source 来执行指令
因为 source 对 script 的执行方式会在父程序中执行的,因此各项动作都会在原本的 bash 内生效!
- test
- [] ——利用判断符号来判断
1、中括号的两端需要有空格符来分隔喔! ——[□"$HOME"□==□"$MAIL"□]
2、在中括号 [] 内的每个组件都需要有空格键来分隔; ——[□"$HOME"□==□"$MAIL"□]
3、在中括号内的变数,最好都以双引号括号起来;
4、在中括号内的常数,最好都以单或双引号括号起来。
5、中括号的使用方法与 test 几乎一模一样啊~ 只是中括号比较常用在条件判断式 if ..... then ..... fi 的情况中就是了
- shell脚本默认的变量
1、
2、shift:造成参数变量号码偏移
- if .... then ——中括号的格式要注意!与上一小节相同
1、基本格式 ——[ ]括号后面是分号!!
2、多个条件判断
注意!!中括号与中括号之间用空格分开
也可以:[ "${yn}" == "Y" -o "${yn}" == "y" ]
3、多重、复杂条件判断式 ——注意是elif而不是else if—— 是else
- 利用 case ..... esac 判断
- 利用 function 功能 ——在 shell script 当中的 function 的设定一定要在程序的最前面,因为程序自上而下
注意:function里面也有$1这个含义在,但这个跟主函数的$1是不一样的,他是局部函数
- while do done ——『当 condition 条件成立时,就进行循环,直到condition 的条件不成立才停止』
输入yes或YES就不会再read
- until do done ——『当 condition 条件成立时,就终止循环, 否则就持续进行循环的程序段。』
- for...do...done (固定循环)
for sitenu in $(seq 1 100) # seq 为 sequence(连续) 的缩写之意
do
.......
doneusers=$(cut -d ':' -f1 /etc/passwd) # 撷取账号名称
#users=$(ls ${dir}) ——有多种表示方法!
for username in ${users} # 开始循环进行!
do
.......
done
- for...do...done 的数值处理
- 搭配随机数与数组的实验
1、shell有一个环境变量RANDOM,范围是0--32767
a)如果我们想要产生0-25范围内的数:$(($RANDOM%26))b)如果想得到1--68范围内的数 : $(($RANDOM%68+1 ))
c)如果想得到6--87范围内的数 : $(($RANDOM%82+6 ))2、linux的数组从零开始,但要是从一开始也可以,那么0的位置即为空。
- debug
[dmtsai@study ~]$ sh [-nvx] scripts.sh
选项与参数:
-n :不要执行 script,仅查询语法的问题;
-v :再执行 sccript 前,先将 scripts 的内容输出到屏幕上;
-x :将使用到的 script 内容显示到屏幕上,这是很有用的参数!
- vim
- 移动光标 ——G,[SPACE],[ENTER]
- 查找与替换 ——/,n,N,:n1,n2s/word1/word2/g(c)
- 删除、复制、粘贴 ——x、X、dd、yy、p、P、u、ctrl+r、.
- 一般指令模式切换到编辑模式 —— i
- 一般指令模式切换到指令列模式 ——q、wq、!
- 区块选择 ——v、V、ctrl+v、y、p、d、D
D是指将区块到此行末尾所有数据删除。
- 多文件编辑 ——n,N,file
- 多窗口功能 ——:sp、:ctrl+w+上、:ctrl+w+下、:ctrl+w+q