马哥学习笔记

第一章、操作系统基础

01_03_操作系统基础

 

计算机体系结构包括以下几部分:

运算器
控制器
存储器,内存,编址
输出设备
输入设备

北桥 - 高速总线控制器

南桥 - 低速总线总线控制器



硬件架构:
ARM
x86
x64
安腾
alpha
UltraSparc
Power
M68000, M68K
PowerPC

OS:
Windows
Linux
Unix
HP-UX
Solaris
AIX
SCO UNIX
Unixware
OS/2

内核功能:
进程管理
内存管理
文件系统
网络功能
硬件驱动
安全机制

批处理系统
jobs1$$$$$$$jobs2$$$$$$$$

下面来讲一个关于操作系统的故事。

        1965年时,贝尔实验室(Bell Labs)加入一项由通用电气(General Electric)和麻省理工学院(MIT)合作 的计划;该计划要建立一套多使用者、多任务、多层次(multi-user、multi-processor、multi-level)的MULTICS操作系统。直到1969年,因MULTICS计划的工作进度太慢,该计划被停了下来。当时,Ken Thompson(后被称为UNIX之父)已经有一个称为"星际旅行"的程序在GE-635的机器上跑,但是反应非常慢,正巧被他发现了一部被闲置的PDP-7(Digital的主机),Ken Thompson和Dernis Ritchie就将"星际旅行"的程序移植到PDP-7上。



        MULTICS其实是"Multiplexed Information and Computing Service"的缩写,在1970年时,那部PDP-7却只能支持两个使用者,当时,Brian Kernighan就开玩笑地称他们的系统其实是:"UNiplexed Information and Computing Service",缩写为"UNICS",后来,大家取其谐音,就称其为"UNIX"了。1970年可称为"UNIX元年"。



        1971年,Ken Thompson写了充分长篇的申请报告,申请到了一台PDP-11/24的机器。于是Unix第一版出来了。在一台PDP-11/24的机器上完成。这台电脑只有24KB的物理内存和500K磁盘空间。Unix占用了12KB的内存,剩下的一半内存可以支持两用户进行Space Travel的游戏。而著名的fork()系统调用也就是在这时出现的。



        到了1973年的时候,Ken Thompson 与Dennis Ritchie感到用汇编语言做移植太过于头痛,他们想用高级语言来完成第三版,对于当时完全以汇编语言来开发程序的年代,他们的想法算是相当的疯狂。一开始他们想尝试用Fortran,可是失败了。后来他们用一个叫BCPL(Basic Combined Programming Language)的语言开发,他们整合了BCPL形成B语言,后来Dennis Ritchie觉得B语言还是不能满足要求,于是就改良了B语言,这就是今天的大名鼎鼎的C语言。于是,Ken Thompson 与Dennis Ritchie成功地用C语言重 写了Unix的第三版内核。至此,Unix这个操作系统修改、移植相当便利,为Unix日后的普及打下了坚实的基础。而Unix和C完美地结合成为一个统一体,C与Unix很快成为世界的主导。



        Unix的第一篇文章 “The UNIX Time Sharing System”由Ken Thompson和Dennis Ritchie于1974年7月的 The Communications of the ACM发表。这是UNIX与外界的首次接触。结果引起了学术界的广泛兴趣并对其源码索取,所以,Unix第五版就以“仅用于教育目的”的协议,提供给各大学作为教学之用,成为当时操作系统课程中的范例教材。各大学公司开始通过Unix源码对Unix进行了各种各样的改进和扩展。于是,Unix开始广泛流行。



        其中,Berkeley成立的由Bill Joy 领导的Unix研究小组取得的成就比较明显。



        然而,20世纪70年代,AT&T公司开始注意到Unix所带来的商业价值。公司的律师开始寻找一些手段来保护Unix,并让其成为一种商业机密。从1979年Unix的版本V7开始,Unix的许可证开始禁止大学使用Unix的源码,包括在授课中学习。(之前由于AT&T公司被美国法院限制不可以销售除电话以外的其它产品,甚至别人向AT&T公司索取时,都不能拒绝,直到贝尔实验室独立了出来)



        到了1980年,有两个最主要的Unix的版本线,一个是Berkeley的BSD UNIX,另一个是AT&T的Unix,在这个时候,很显然,竞争最终引发了Unix的战争。在这场战争中,好的是,软件开发人员还是能够得到Unix的源码并对其按照自己的需要和兴致进行裁剪。而不好的是,Unix开始一发不可收拾地开发不停地出现各种各样的变种。



        1982年,Joy创建了Sun Microsystems公司并提供了工作站–Sun-1,运行SunOS(Solaris以之后的十年出现)。而AT&T则在随后的几年中发布了Unix System V的第一版,一个具有强大影响力的操作系统,最终造就了IBM的AIX和HP的HP-UX。

        正值Unix战争之际,微软公司Bill Gates依靠母亲在IBM任职董事会副主席的关系,取得为其新PC机编写关键的操作系统软件的合作。由于时间紧迫,程序复杂,微软公司以5万美元的价格从西雅图的一位程序编制者Tim Paterson(帕特森)手中买下了一个操作系统QDOS的使用权,在进行部分改写后提供给IBM,并将其命名为Microsoft DOS(Disk Operating System,磁盘操作系统)。

        另一家出名的电脑公司苹果,从施乐公司买进一个结合了鼠标的图形操作系统,该产品被认为会侵害施乐公司复印机业务。



        微软利用与苹果合作的关系,抄袭了这款操作系统,发行了windows 1.0。但依然基于DOS,非常容易崩溃。微软从DEC雇佣了一批人员使用DEC的一个操作系统框架开发了新一代系统Window NT。



        Unix收费后,Andrew开发的 Minix(一种基于微内核架构的类UNIX计算机操作系统)开始流行,Minix最有名的学生用户是Linus Torvalds,他在芬兰的赫尔辛基大学用Minix操作平台建立了一个新的操作系统的内核,他把它叫做Linux。

        80年代,Stallman 发起了GNU计划,GNU是“GNU's Not Unix”的递归缩写。加入GUN的软件都是自由并开源的,接受GNU通用公共许可证(GNU General Public License,GPL)。但发布的软件都依赖于Unix,这和GUN is Not Unix的定义严重不符。Linux诞生时就是在GPL条款下发布。1992年Linux与其他GNU软件结合,完全自由的操作系统正式诞生。GPL规定使用了GPL的软件后,你自己的软件也必须开源,这限制了GPL的普及,后来LGPL的出现改变了这一状况(LGPL: Lesser General Public License),GNU的软件有:
    Emacs: 文本编辑器
    gcc: GNU C Complier
    bash: 
    Linux:glibc, gcc, 
    GNU/Linux

自由软件中自由是指:
自由获取,自由修改,自由学习



Linux发行版
        GNU/Linux都是以源的形式发布,需要自行编译,使用起来十分复杂,门槛太高。然后就有了Linux发行商。
RedHat
SLS
Debian
SUSE --> Novell (Netware), OpenSUSE

Ubuntu: Mint
CentOS: Community ENTerprise OS, 社区版红帽
Fedora: 个人版红帽,RedHat公司已经将个人版红帽交给了Fedora社区



两大软件包管理软件
Debian, dpt
RedHat, rpm


RedHat开机配置
linux ip=172.16.X.1 netmask=255.255.0.0 gateway=172.16.0.1 dns=172.16.0.1 ks=http://172.16.0.1/class.cfg

Linux内核版本和RHEL版本号可不一样

Linux: 0.1, 1.0, 2.0, 2.2, 2.4, 2.6, 3.0, 3.7
RHEL 3.0, 4.0, 5.0, 6.0

第二章、Linux操作系统及常用命令



02_01_Linux操作系统及常用命令



Linux的基本原则:
1、由目的单一的小程序组成;组合小程序完成复杂任务;
2、一切皆文件;
3、尽量避免捕获用户接口;
4、配置文件保存为纯文本格式;

GUI接口:Graphical User Interface
CLI接口:command-line interface


命令提示符,prompt, bash(shell)
#: root
$: 普通用户


命令格式: 命令  选项  参数

# command  options...  arguments...
选项:
    短选项: -
        多个选项可以组合:-a -b = -ab
    长选项: --


参数:命令的作用对象

虚拟终端(terminal):Ctrl+Alt+F1-F6
模拟终端:GUI图形界面中的终端

GUI:
    X-Window Gnome: C    KDE: C++    XFace

CLI:
    sh    bash    csh    zsh    ksh    tcsh


root, student, vistor

1. su: switch user
# su [-l] 用户名 完全切换
# passwd

密码复杂性规则:
10^6
36^6
62^6
100^6


[email protected]
1、使用4种类别字符中至少3种;
2、足够长,大于7位;
3、使用随机字符串;
4、定期更换;
5、循环周期足够大;

以后的课程大概包括:
RHCE+RHCA+shell编程+MySQL+Web集群+NoSQL+Hadoop+Hbase+Openstack

内部FTP:
172.16.100.177
192.168.0.1

google hack:
linux filetype:pdf
linux site:ibm.com

IDE:


login:
    用户名:用户ID

认证机制:Authentication
授权:Authorization
审计:Audition (日志)

prompt,命令提示符:

magic number: 魔数,标记可执行文件的格式,exe,elf

#!/bin/bash就是脚本的魔数,又称shebang

2. ls: list
列出,列表

目录:文件,路径映射
路径:从指定起始点到目的地所经过位置
文件系统:file system

 

ls

         -l:长格式

                   文件类型:

                      

                             -:普通文件 (f)

                            d: 目录文件

                            b: 块设备文件 (block)

                            c: 字符设备文件 (character)

                            l: 符号链接文件(symbolic link file)

                            p: 命令管道文件(pipe)

                            s: 套接字文件(socket)

                   文件权限:9位,每3位一组,每一组:rwx(读,写,执行), r--

                   文件硬链接的次数

                   文件的属主(owner)

                   文件的属组(group)

                   文件大小(size),单位是字节

                   时间戳(timestamp):最近一次被修改的时间

                            访问:access

                            修改:modify,文件内容发生了改变

                            改变:change,metadata,元数据

         -h:做单位转换

         -a: 显示以.开头的隐藏文件

                   . 表示当前目录

                   .. 表示父目录

         -A

         -d: 显示目录自身属性

         -i: index node, inode

         -r: 逆序显示

         -R: 递归(recursive)显示

3. pwd: Printing Working directory     

目录:working directory, current directory

 

 

4. cd: change directory

         家目录,主目录, home directory

         cd ~USERNAME: 进入指定用户的家目录

         cd -:在当前目录和前一次所在的目录之间来回切换



5. type: 显示指定属于哪种类型

Linux命令类型:

         内置命令(shell内置),内部,内建

         外部命令:在文件系统的某个路径下有一个与命令名称相应的可执行文件

        

环境变量:命名的内存空间

         变量赋值       NAME=Jerry

         PATH: 使用冒号分隔的路径

 

6. hash: 查看命令缓存

       时间复杂度:O(1)

缓存为王,cache is king

  

02_02_Linux操作系统及常用命令

     

7. date:时间管理,查看系统时钟

Linux:  开机时读取硬件时钟,软件模拟生成系统时钟。

    date  [MMDDhhmm[[CC]YY][.ss]]  //月 日 小时 分钟 年 . 秒

    修改系统时间,如:date 1228235912.30 或 date 122823592012.30



    date [OPTION]... [+FORMAT]

    date +%D  ---- 月/日/年

    date +"This year is %Y, %n Today is %d"



8. clock/hwclock: 查看硬件时钟

clock和hwclock用法相近,只不过clock命 令除了支持x86硬件体系外,还支持Alpha硬件。

         -w: 系统时钟写入硬件时钟

         -s: 硬件时钟写入系统时钟

 

 

9. man: 显示命令manual pages

获得命令的使用帮助方式:

(1)内部命令:

         help COMMAND (提示:man + 内部命令 查看到的是shell的帮助)

(2)外部命令:

         COMMAND --help  

(3)命令手册:manual

        man COMMAND

(4)在线文档:

        info COMMAND

(5)文档:/usr/share/doc

(6)google



MAN pages中各个小章节:

         NAME:命令名称及功能简要说明

         SYNOPSIS:用法说明,包括可用的选项

                使用格式说明中的符号:

                    <>:必选

                    []:可选

                    ...:可以出现多次

                    |:多选一

                    {}:分组

         DESCRIPTION:命令功能的详尽说明,可能包括每一个选项的意义

         OPTIONS:说明每一个选项的意义

         FILES:此命令相关的配置文件

         BUGS:

         EXAMPLES:使用示例

         SEE ALSO:另外参照

 

man pages中操作:

翻屏:

         向后翻一屏:f / SPACE

         向前翻一屏:b

         向后翻一行:j / ENTER

         向前翻一行:k

 

查找:

/KEYWORD: 向后

n: 下一个, N:前一个

 

?KEYWORD:向前

n: 下一个, N:前一个

 

退出:q

 

 

 

10. whatis COMMAND: 查看该命令属于那些章节

 

man分章节:

1:用户命令(/bin, /usr/bin, /usr/local/bin)

2:系统调用

3:库用户

4:特殊文件(设备文件)

5:文件格式(配置文件的语法)

6:游戏

7:杂项(Miscellaneous)

8:管理命令(/sbin, /usr/sbin, /usr/local/sbin)

 

练习:

         使用date单独获取系统当前的年份、月份、日、小时、分钟、秒

        date +%Y, date +%m, date +%d, date +%H, date +%M, date +%S



11. cal: calendar

     cal 2013: 查看2013年日历

     cal 12 2013: 查看2013年12月日历

 

练习:

1、echo是内部命令还是外部命令?

2、其作用?

3、如何显示“The year is 2013. Today is 26.”为两行?

 

1、type echo

2.、man type

3、echo -e "The year is 2013. \nToday is 26." 

 

12. echo: 回声

    -n 不换行

    -e 开启转义字符

 

练习:

1、printf是内部命令还是外部命令?

2、其作用?

3、如何显示“The year is 2013. Today is 26.”为两行?

 

1、type printf

2、man printf

3、printf "The year is 2013. \nToday is 26.\n"



13. printf: 打印

类似printf 函数用法

printf "The year is %d. \nToday is %d.\n" `date +%Y` `date +%d`



14. file:确定文件格式

Windows: PE

Linux: ELF

 第三章、Linux根文件系统及文件管理命令详解



02_03_Linux根文件系统详解



文件系统:

rootfs: 根文件系统

 

FHS:Filesystem Hierarchy Standard(文件系统目录标准)的缩写,多数Linux版本采用这种文件组织形式,类似于Windows操作系统中c盘的文件目录,FHS采用树形结构组织文件。FHS定义了系统中每个区域的用途、所需要的最小构成的文件和目录,同时还给出了例外处理与矛盾处理。



根目录下的目录:

/boot: 系统启动相关的文件,如内核、initrd,以及grub(bootloader)

/dev: 设备文件

         设备文件:

                   块设备:随机访问,数据块

                   字符设备:线性访问,按字符为单位

                   设备号:主设备号(major)和次设备号(minor)

/etc:配置文件

/home:用户的家目录,每一个用户的家目录通常默认为/home/USERNAME

/root:管理员的家目录;

/lib:库文件

         静态库,  .a

         动态库, .dll, .so (shared object)

         /lib/modules:内核模块文件

/media:挂载点目录,移动设备

/mnt:挂载点目录,额外的临时文件系统

/opt:可选目录,第三方程序的安装目录

/proc:伪文件系统,内核映射文件

/sys:伪文件系统,跟硬件设备相关的属性映射文件

/tmp:临时文件, /var/tmp

/var:可变化的文件

/bin: binary 可执行文件, 用户命令

/sbin:管理命令

 

/usr:universal shared read-only 

    有的说全称为:User System Resources, 见 http://www.ansen.org/2011/11/means-of-usr.html

         /usr/bin

         /usr/sbin

         /usr/lib

        

/usr/local:

         /usr/local/bin

         /usr/local/sbin

         /usr/local/lib

 

文件命名规则:

1、长度不能超过255个字符;

2、不能使用/当文件名

3、严格区分大小写

 

相对路径:以"./"开头的路径,默认

绝对路径: 以"/"开头的路径

 

使用一个操作系统主要工作:

文件管理

目录管理

运行程序

设备管理

软件管理

网络管理

        

目录管理

前面介绍过的:ls、cd、pwd

 

1. mkdir:创建空目录

         -p:

         -v: verbose

 

mkdir -pv /mnt/test/x/m /mnt/test/y

mkdir -pv /mnt/test/{x/m,y}

 

波浪线展开:~USERNAME



命令行展开:

在/mnt/test2/下创建a_b, a_c, d_b, d_c 四个目录

(a+d)(b+c)=ab+ac+db+dc

mkdir /mnt/test2/{a,d}_{b,c}  #作为一个参数中间不可有空格

 

2. tree:查看目录树

 

3. rmdir (remove directory) 删除目录

         删除空目录

         -p 如果父目录为空,同样删除

        

文件创建和删除

4. touch修改文件时间戳

         -a 仅修改访问时间

         -m 仅修改修改时间

         -t  指定时间为 [[CC]YY]MMDDhhmm[.ss]

         -c 不创建文件



5. stat:显示文件状态

    包括: 访问,修改,改变时间



创建文件,可以使用文件编辑器 nano

 

6. rm:删除文件

         -i interactive 交互式

         -f force 强制

         -r recursive 递归

        

练习:

1、创建目录

(1)在/mnt下创建boot和sysroot;

(2)在/mnt/boot下创建grub;

(3)在/mnt/sysroot下创建proc, sys, bin, sbin, lib, usr, var, etc, dev, home, root, tmp

         a)在/mnt/sysroot/usr下创建bin, sbin, lib

         b)在/mnt/sysroot/lib下创建modules

         c)在/mnt/sysroot/var下创建run, log, lock

         d)在/mnt/sysroot/etc下创建init.d

        

(1) mkdir /mnt/{boot,sysroot}

(2) mkdir /mnt/boot/grub

(3) mkdir -p /mnt/sysroot/{proc,sys,bin,sbin,lib/modules,usr/{bin,sbin,lib},var{run,log,lock},etc/init.d,dev,home,root,tmp} 

 

02_04_Linux文件管理命令详解

 

复制和移动文件

7. cp: copy

cp SRC DEST

         -R, -r, --recursive 递归

         -i,--interactive 交互

         -f --force 强制

         -p   same as --preserve=mode,ownership,timestamps

         -P,--no-dereference      never follow symbolic links in SOURCE

         -L, --dereference            always follow symbolic links in SOURCE

         -d  same as --no-dereference --preserve=links 

         -a,--archive  same as -dR --preserve=all 归档复制,常用于备份

        

cp file1 file2 file3

一个文件到一个文件

多个文件到一个目录

cp /etc/{passwd,inittab,rc.d/rc.sysinit} /tmp/

 

复制文件时如果目标存在。1. 目标为文件,提示覆盖。2. 目标为目录,复制的文件放到目录下。

复制目录时如果目标存在。1.目标为文件,无法覆盖。2. 目标为目录,复制源目录下所有文件到新目录下,如果文件重复,提示覆盖。



8. mv: move 移动文件

 

mv SRC DEST

mv -t DEST SRC

 

9. install: 复制文件并设置属性

         -d DIRECOTRY ... :创建目录

         SRC DEST

          -t 指定目录

          -m 设置权限

install -t DIRECTORY SRC...



install 不能复制目录。 



作业1:

1、创建目录/backup

# mkdir -v /backup

2、复制目录/etc至/backup目录中,并重命名为“etc-当前日期”,如etc-2013-02-26;要求保留文件原来的属性,保持链接文件;

# cp -a /etc /backup/etc-2013-02-28  

3、复制文件/etc/inittab为/tmp/inittab.new,并删除inittab.new文件的后两行;

# cp /etc/inittab  /tmp/inittab.new

# nano /tmp/inittab.new

 

作业2:

1、思考:ls命令是否可以显示某目录的整体大小,即包括其内部的所有文件的整体大小?

2、通过帮助手册,学习使用du命令;

3、通过帮助,学习read命令;

 

1、不能,du可以

2、du -s -h

3、read var

 

03_01_Linux文件管理类命令详解



作业3:

描述GPL, BSD, Apache三个开源协定的大体联系及区别。

 

自由软件

开源协定,版权描述

 

作业4:

1、如何获取Linux当前最新的内核版本号?

         www.kernel.org

2、列出你所了解的Linux发行版,并说明其跟Linux内核的关系。

         Linux, GNU: GNU/Linux, 源代码

        

         发行版:Fedora, RedHat(CentOS), SUSE, Debian(Ubuntu, Mint), Gentoo, LFS(Linux From Scratch)

        

RedHat: 通用格式,为了能支持大多数的CPU,编译出来的二进制可执行程序在较低平台上编译。为了发挥硬件最大性能,自己编译一个针对自己平台的Linux,Gento和LFS提供了这种方式。

 

复习:

运行程序

设备管理

软件管理

进程管理

网络管理

 

目录管理:

ls、cd、pwd、mkdir、rmdir、tree

 

文件管理:

touch、stat、file、rm、cp、mv、nano

 

日期时间:

date、clock、hwclock、cal

 

查看文本:

cat、tac、more、less、head、tail

 

10. cat:连接并显示

         -n 显示行号

         -E Show end, 行尾显示$

        

shift + pageup/pagedown 在终端缓存中翻页

分屏显示:

more、less

 

11. more: 向后翻

12. less:

 man命令就是在用less命令查看文档。

 

13. head:查看前n行

    n 默认为10

head -n 2 == head -2



14. tail:查看后n行

         -n 默认为10    

tail -f: 查看文件尾部,不退出,等待显示后续追加至此文件的新内容;

 

文本处理:

cut、join、sed、awk

 

文本文件:

Tom:23:male:2013/05/06

 

15. cut:

         -d: 指定字段分隔符,默认是空格

         -f: 指定要显示的字段

                   -f 1,3

                   -f 1-3

 

16. sort : 文本排序

         -n:数值排序

         -r: 降序

         -t, --field-separator=SEP: 字段分隔符

         -k, --key=POS1[,POS2]: 以哪个字段为关键字进行排序

         -u: 排序后相同的行只显示一次

         -f: 排序时忽略字符大小写

        

17. uniq: 去掉重复的行(必须相邻)

         -c, --count: 显示文件中行重复的次数

         -d, --repeated:  only print duplicate lines 只显示重复的行

        

18. wc: (word count) 文本统计

         -l, --lines 只显示行数

         -w, --words 

         -c, --bytes

         -L, --max-line-length 

 

不使用参数,默认显示:行,单词,字节数



19. tr:字符处理命令 —— 转换或删除字符

tr [OPTION]... SET1 [SET2]

         -d: 删除出现在字符集中的所有字符(只能有SET1)

 把SET1中字符转换成SET2中字符,SET1 和SET2一对应, 如:tr ab AB, 会把a 换成A,b换成B

第四章、bash特性详解



03_02_base特性详解 



bash及其特性:

shell: 外壳

GUI:Gnome, KDE, Xfce

CLI: sh, csh, ksh, bash, tcsh, zsh

 

Linux允许同一个用户登录多次

root, student

程序:进程

 

进程:在每个进程看来,当前主机上只存在内核和当前进程

进程是程序的副本,进程是程序执行实例

 

用户工作环境:

bash:

         #

         $

        

shell,子shell

bash--bash

 

bash:

1、命令历史、命令补全

2、管道、重定向

3、命令别名

4、命令行编辑

5、命令行展开

6、文件名通配

7、变量

8、编程

 

命令行编辑:

光标跳转:

         Ctrl+a:跳到命令行首

         Ctrl+e:跳到命令行尾

         Ctrl+u: 删除光标至命令行首的内容

         Ctrl+k: 删除光标至命令行尾的内容

         Ctrl+l: 清屏

        

命令历史:

查看命令历史:history

         -c:清空命令历史

         -d OFFSET [n]: 删除指定位置的命令

         -w:保存命令历史至历史文件中

        

环境变量

PATH:命令搜索路径

HISTSIZE: 命令历史缓冲区大小

 

命令历史的使用技巧:推荐一篇文章《让效率翻倍的Bash技巧》

!n:执行命令历史中的第n条命令;

!-n:执行命令历史中的倒数第n条命令;

!!: 执行上一条命令;

!string:执行命令历史中最近一个以指定字符串开头的命令

!$:引用前一个命令的最后一个参数;  

Esc, .:引用前一个命令的最后一个参数;

Alt+.

 

命令补全: tab

         搜索环境变量PATH记录的路径。

路径补全:tab

 

文本相关的命令

查看:cat, tac, more, less, head, tail

统计:wc

处理:tr, cut, join

排序:sort

uniq





03_03_base特性详解 

 

复习:

bash特性:

命令行编辑:

命令历史:

         history           -c         -w          -d

         HISTSIZE

         ~/.bash_history

 

!n, !-n, !!, !string, !$

 

命令补全,路径补全

命令补全:搜索PATH环境变量所指定的每个路径下以我们给出的字符串开头的可执行文件,如果多于一个,两次tab,可以给出列表;否则将直接补全;

路径补全:搜索我们给出的起始路径下的每个文件名,并试图补全;

 

命令别名

定义:alias CMDALIAS='COMMAND [options] [arguments]'

在shell中定义的别名仅在当前shell生命周期中有效;别名的有效范围仅为当前shell进程;

 

取消:unalias CMDALIAS

 

使用命令本身: \CMD

 

命令替换: $(COMMAND), 反引号:`COMMAND`

把命令中某个子命令替换为其执行结果的过程

eg:

1. echo "The current directory is $(pwd)."

2. echo "file-$(date +%F-%H-%M-%S)"   -------------  file-2013-02-28-14-53-31.txt

    %F     full date; same as %Y-%m-%d

    %H     hour (00..23)

    %M     minute (00..59)

    %S     second (00..60)

    %T     time; same as %H:%M:%S

 

bash支持的引号

``: 反引号,命令替换

"": 弱引用,可以实现变量替换

'': 强引用,不完成变量替换

 

文件名通配, globbing

*: 任意长度的任意字符

?:任意单个字符

[]:匹配指定范围内的任意单个字符

         [abc], [a-m], [a-z], [A-Z], [0-9], [a-zA-Z], [0-9a-zA-Z]

         [:space:]:空白字符

         [:punct:]:标点符号

         [:lower:]:小写字母

         [:upper:]: 大写字母

         [:alpha:]: 大小写字母

         [:digit:]: 数字

         [:alnum:]: 数字和大小写字母

        

# man 7 glob 查看这些内置特殊字符表示



[^]: (脱字符) 匹配指定范围之外的任意单个字符

 

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

 

练习:

1、创建a123, cd6, c78m, c1 my, m.z, k 67, 8yu, 789等文件;注意,以上文件是以逗号隔开的,其它符号都是文件名的组成部分;

2、显示所有以a或m开头的文件;

ls [am]*

3、显示所有文件名中包含了数字的文件;

ls *[0-9]*

ls *[[:digit:]]*

4、显示所有以数字结尾且文件名中不包含空白的文件;

ls *[^[:space:]]*[0-9]   ?????????    --  正则表达式可以解决

5、显示文件名中包含了非字母或数字的特殊符号的文件;

ls *[^[:alnum:]]*

ls *[^a-zA-Z0-9]*

 第五章、Linux用户及权限详解



03_04_Linux用户及权限详解

 

今天内容:

用户、组、权限

 

用户,用户组: 都只是标识符

 

安全上下文(secure context):

 

权限:

r, w, x

 

文件:

r:可读,可以使用类似cat等命令查看文件内容;

w:可写,可以编辑或删除此文件;

x: 可执行,eXacutable,可以命令提示符下当作命令提交给内核运行;

 

目录:

r: 可以对此目录执行ls以列出内部的所有文件;

w: 可以在此目录创建文件;

x: 可以使用cd切换进此目录,也可以使用ls -l查看内部文件的详细信息;

 

rwx:

         r--:只读

         r-x:读和执行

         ---:无权限

        

0 000 ---:无权限

1 001 --x: 执行

2 010 -w-: 写

3 011 -wx: 写和执行

4 100 r--: 只读

5 101 r-x: 读和执行

6 110 rw-: 读写

7 111 rwx: 读写执行

 

755:rwxr-xr-x:属主 属组 其他

 

rw-r-----: 640

 

660: rw-rw----

rwxrwxr-x: 775

 

用户:UID, /etc/passwd

:GID, /etc/group

 

影子口令

用户:/etc/shadow

组:/etc/gshadow

 

用户类别:

管理员:0

普通用户: 1-65535

         系统用户:1-499, 不需要登录系统,只用来运行某些后台服务

         一般用户:500-60000

 

用户组类别:

管理员组:

普通组:

         系统组:

         一般组:

        

用户组类别:

         私有组:创建用户时,如果没有为其指定所属的组,系统会自动为其创建一个与用户名同名的组

         基本组:用户的默认组

         附加组,额外组:默认组以外的其它组

    

e.g:    

进程:tom tom

对象:rwxrw-r--  jerry tom a.txt

 

tom执行ls命令

rwxr-xr-x root root /bin/ls, 文件属主各属组



ls 运行时,进程的属主是运行的用户

 

man 5 passwd

/etc/passwd

account: 登录名

password: 密码

UID:

GID:基本组ID

comment: 注释

HOME DIR:家目录

SHELL:用户的默认shell, cat /etc/shells查看合法shell

 

man 5 shadow: 查看/etc/shadow文件格式

/etc/shadow

account: 登录名

encrypted password: 加密的密码,两个!号表示锁定,不允许登录。格式: $1位$8位$密码

 

1位段: 加密方法

8位段:杂质(随机生成)



加密方法:

         对称加密:加密和解密使用同一个密码

         公钥加密:每个密码都成对儿出现,一个为私钥(secret key),一个为公钥(public key)

         单向加密,散列加密:提取数据特征码,常用于数据完整性校验

                  特性: 1、雪崩效应  2、定长输出

                  MD5:Message Digest, 128位定长输出

                  SHA1:Secure Hash Algorithm, 160位定长输出

 

非对称加密更长,速度慢,慢3个数量级(1000倍以上) 



用户,组添加

useradd USERNAME

groupadd GRPNAME

 

用户管理:

         useradd, userdel, usermod, passwd, chsh, chfn, finger, id, chage

 

组管理:

         groupadd, groupdel, groupmod, gpasswd

        

权限管理:

         chown, chgrp, chmod, umask

 

 

/etc/passwd:

用户名:密码:UID:GID:注释:家目录:默认SHELL

 

/etc/group:

组名:密码:GID:以此组为其附加组的用户列表

 

/etc/shadow:

用户名:密码:最近一次修改密码的时间:最短使用期限:最长使用期限:警告时间:非活动时间:过期时间:

 

用户管理:

         useradd, userdel, usermod, passwd, chsh, chfn, finger, id, chage

 



 04_01_Linux用户管理命令详解



1. useradd  [options]  USERNAME

         -u UID

         -g GID(基本组)

         -G GID,...  (附加组) 一个用户可以属于多个附加组

         -c "COMMENT"

         -d /path/to/directory  指定家目录

         -s SHELL ; /etc/shells:指定了当前系统可用的安全shell

         -m  -k  创建家目录,并复制SKEL_DIR(default: /etc/skel) 下的文件到家目录

         -M 不创建用户主目录,即使系统在 /etc/login.defs 中的设置 (CREATE_HOME) 为 yes。

         -r: 添加系统用户

        

/etc/login.defs  用户操作的一些选项

 

环境变量:

         PATH

         HISTSIZE

         SHELL



 

2. userdel:

userdel [option] USERNAME

         -r: 同时删除用户的家目录

 

3. id:查看用户的帐号属性信息

         -u 显示uid

         -g 显示基本组id

         -G 显示附加组id

         -n 显示名称,而非ID号,结合其它选项

 

4. finger: 查看用户帐号信息

finger USERNAME

 

5. usermod: 修改用户帐号属性

         -u UID

         -g GID

         -a -G GID:不使用-a选项,会覆盖此前的附加组;

         -c "COMMENT"

         -d -m:修改家目录,并复制原家目录下文件到新家目录下

         -s :  shell

         -l : 修改用户名

         -L:锁定帐号

         -U:解锁帐号

        

6. chsh: 修改用户的默认shell

 

7. chfn:change finger 修改更改真名和信息,注释信息

 

8. passwd [USERNAME]: 密码管理

         --stdin  从标准输入接收密码, echo "redhat" | passwd --stdin root

         -l  lock

         -u unlock

         -d: 删除用户密码

 

9. pwck:检查用户帐号完整性

 

组管理:

10. groupadd创建组

         -g GID

         -r:添加为系统组

        

11. groupmod

         -g GID

         -n GRPNAME

 

12. groupdel

 

13. gpasswd:为组设定密码

 

14. newgrp GRPNAME <--> exit(退出临时组): 临时切换为其他基本组,这时候需要用到组密码(切换到自己的附加组不需要)

        

 

练习:

1、创建一个用户mandriva,其ID号为2002,基本组为distro(组ID为3003),附加组为linux;

# groupadd -g 3003 distro

# groupadd linux

# useradd -u 2002 -g distro -G linux mandriva

2、创建一个用户fedora,其全名为Fedora Community,默认shell为tcsh;

# useradd -c "Fedora Community" -s /bin/tcsh fedora

3、修改mandriva的ID号为4004,基本组为linux,附加组为distro和fedora;

# usermod -u 4004 -g linux -G distro,fedora mandriva

4、给fedora加密码,并设定其密码最短使用期限为2天,最长为50天;

# passwd -n 2 -x 50 fedora

 

5、将mandriva的默认shell改为/bin/bash;

usermod -s /bin/bash mandirva

6、添加系统用户hbase,且不允许其登录系统;

# useradd -r -s /sbin/nologin hbase

7、

 

chage:修改用户密码过期时间

         -d: 最近一次的修改时间

         -E: 过期时间

         -I:非活动时间

         -m: 最短使用期限

         -M: 最长使用期限

         -W: 警告时间

 

04_02_权限及权限管理



复习:

权限管理:

r:

w:

x:

 

三类用户:

u: 属主

g: 属组

o: 其它用户

 

1. chown: 改变文件属主(只有管理员可以使用此命令)

# chown USERNAME file,...

         -R: 修改目录及其内部文件的属主

         --reference=/path/to/somefile file,...

 

chown USERNAME:GRPNAME file,...

chown USERNAME.GRPNAME file,...

        

2. chgrp: 改变文件属组

# chgrp GRPNAME file,...

         -R:recursive

         --reference=/path/to/somefile file,...

        

3. chmod: 修改文件的权限

修改三类用户的权限:

chmod MODE file,...

         -R:recursive

         --reference=/path/to/somefile file:参考某个文件设定权限

 

修改某类用户或某些类用户权限:

u,g,o,a

chmod 用户类别=MODE file,...



e.g: chmod go=rw,u=r /tmp/abc



修改某类用户的某位或某些位权限:

u,g,o,a

chmod 用户类别+|-MODE file,...

chmod u-x /tmp/abc

chmod u+x,g-x /tmp/abc

chmod u-rx /tmp/abc



 

练习:

1、新建一个没有家目录的用户openstack;

# useradd -M openstack

2、复制/etc/skel为/home/openstack;

# cp -r /etc/skel /home/openstack

3、改变/home/openstack及其内部文件的属主属组均为openstack;

# chown -R openstack:openstack /home/openstack

4、/home/openstack及其内部的文件,属组和其它用户没有任何访问权限

# chmod -R go= /home/openstack

 

 

手动添加用户hive, 基本组为hive (5000),附加组为mygroup

    1. 修改/etc/passwd文件,data +%s 得到19700101到当前的秒数,使用bc(bc是Linux下的计算器)把秒数除以一天的秒数86400,得到19700101到今天的天数。

    2. 创建家目录、复制文件、修改文件权限

    3. 修改/etc/shadow文件,使用sslpasswd可以生成加盐的加密串。

openssl passwd -1 -salt '12345678' 

 

4. umask:遮罩码

文件:666-umask

目录:777-umask

 

# umask

# umask 022

 

文件默认不能具有执行权限,如果算得的结果中有执行权限,则将其权限加1;

 

umask: 023

文件:666-023=643 X

目录:777-023=754

 

站在用户登录的角度来说,SHELL的类型

登录式shell:

         正常通常某终端登录

         1. su - USERNAME

         2. su -l USERNAME

 

非登录式shell:

         1. su USERNAME

         2. 图形终端下打开命令窗口

         3. 自动执行的shell脚本

        

 

bash的配置文件:

全局配置

         /etc/profile, /etc/profile.d/*.sh, /etc/bashrc

个人配置

         ~/.bash_profile, ~/.bashrc

        

profile类的文件:

         设定环境变量

         运行命令或脚本

 

bashrc类的文件:

         设定本地变量

         定义命令别名

        

登录式shell如何读取配置文件?

/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc

 

非登录式shell如何配置文件?

~/.bashrc --> /etc/basrc --> /etc/profile.d/*.sh

 

第六章、管道及IO重定向



04_03_管道及IO重定向

 

计算机组成:

运算器、控制器: CPU

存储器:RAM

输入设备/输出设备

 

程序:指令和数据

 

控制器:指令

运算器:

存储器:

 

地址总线:内存寻址

数据总线:传输数据

控制总结:控制指令

 

寄存器:CPU暂时存储器

 

I/O: 硬盘,

 

程序

 

INPUT设备、OUTPUT设备

 

系统设定

         默认输出设备:标准输出,STDOUT, 1

         默认输入设备:标准输入, STDIN, 0

         标准错误输出:STDERR, 2

        

标准输入:键盘

标准输出和错误输出:显示器

 

I/O重定向:

 

Linux:

>: 覆盖输出

>>:追加输出

 

set -C: 禁止对已经存在文件使用覆盖重定向;

            强制覆盖输出,则使用 >|

set +C: 关闭上述功能

 

2>: 重定向错误输出

2>>: 追加方式

 

&>: 重定向标准输出或错误输出至同一个文件

 

<:输入重定向

<<:Here Document,在此处生成文档

    cat >> /tmp/myfile.txe << EOF,可以在脚本中生成文档

 

 

管道:前一个命令的输出,作为后一个命令的输入

 

命令1 | 命令2 | 命令3 | ...

 

tee

    既保存文档,又输出到屏幕 

 

练习:

1、统计/usr/bin/目录下的文件个数;

# ls /usr/bin | wc -l

2、取出当前系统上所有用户的shell,要求,每种shell只显示一次,并且按顺序进行显示;

# cut -d: -f7 /etc/passwd | sort -u

3、思考:如何显示/var/log目录下每个文件的内容类型?

 

4、取出/etc/inittab文件的第6行;

# head -6 /etc/inittab | tail -1

5、取出/etc/passwd文件中倒数第9个用户的用户名和shell,显示到屏幕上并将其保存至/tmp/users文件中;

# tail -9 /etc/passwd | head -1 | cut -d: -f1,7 | tee /tmp/users

6、显示/etc目录下所有以pa开头的文件,并统计其个数;

# ls -d /etc/pa* | wc -l

7、不使用文本编辑器,将alias cls=clear一行内容添加至当前用户的.bashrc文件中;

# echo "alias cls=clear" >> ~/.bashrc

第七章、grep及正则表达式



04_04_grep及正则表达式 



grep家族: grep, egrep, fgrep  

 

grep: 根据模式搜索文本,并将符合模式的文本行显示出来。

Pattern: 文本字符和正则表达式的元字符组合而成匹配条件

 

grep [options] PATTERN [FILE...]

         -i:忽略大小写

         --color:匹配到的字符带颜色

         -v::显示没有被模式匹配到的行

         -o:只显示被模式匹配到的字符串

 

通配符:  

1. *: 任意长度的任意字符

2. ?: 任意单个字符

3. []:

4. [^]:  

 

正则表达式:REGular EXPression, REGEXP

元字符:

1. .: 匹配任意单个字符

2. []: 匹配指定范围内的任意单个字符

3. [^]:匹配指定范围外的任意单个字符

         字符集合:[:digit:], [:lower:], [:upper:], [:punct:], [:space:], [:alpha:], [:alnum:]

 

匹配次数(贪婪模式):

1. *: 匹配其前面的字符任意次       

         e.g: 有:a, b, ab, aab, acb, adb, amnb,下面pattern会匹配那些字符串?

                 a*b: b, ab,aab

                 a?b: b, ab

                 a.*b: ab, aab, acb, adb, amnb

 

         .*: 任意长度的任意字符

2. \?: 匹配其前面的字符1次或0次

3. \{m,n\}:匹配其前面的字符至少m次,至多n次

         \{1,\} - 至少1次

         \{0,3\} - 至多3次

 

位置锚定

1. ^: 锚定行首,此字符后面的任意内容必须出现在行首

2. $: 锚定行尾,此字符前面的任意内容必须出现在行尾

    ^$: 空白行

 

3. \<或\b: 锚定词首,其后面的任意字符必须作为单词首部出现

4. \>或\b: 锚定词尾,其前面的任意字符必须作为单词的尾部出现

 

分组:

\(\)

         \(ab\)*:ab作为整体,出现n次

         后向引用

         \1: 引用第一个左括号以及与之对应的右括号所包括的所有内容

         \2:

         \3:

 

e.g:        

He love his lover.

She like her liker.

He like his lover.

 

grep '\(l..e\).*\1' test.txt 匹配到1, 2行

 

练习:

1、显示/proc/meminfo文件中以不区分大小的s开头的行;

grep -i '^s' /proc/meminfo

grep '^[sS]' /proc/meminfo

2、显示/etc/passwd中以nologin结尾的行;

grep 'nologin$' /etc/passwd

 

取出默认shell为/sbin/nologin的用户列表

grep "nologin$' /etc/passwd | cut -d: -f1

 

取出默认shell为bash,且其用户ID号最小的用户的用户名

grep 'bash$' /etc/passwd | sort -n -t: -k3 | head -1 | cut -d: -f1

 

3、显示/etc/inittab中以#开头,且后面跟一个或多个空白字符,而后又跟了任意非空白字符的行;

grep "^#[[:space:]]\{1,\}[^[:space:]]" /etc/inittab

 

4、显示/etc/inittab中包含了:一个数字:(即两个冒号中间一个数字)的行;

grep ':[0-9]:' /etc/inittab

 

5、显示/boot/grub/grub.conf文件中以一个或多个空白字符开头的行;

grep '^[[:space:]]\{1,\}' /boot/grub/grub.conf

 

6、显示/etc/inittab文件中以一个数字开头并以一个与开头数字相同的数字结尾的行;

grep '^\([0-9]\).*\1$' /etc/inittab

 

练习:

1、找出某文件中的,1位数,或2位数;

grep '[0-9]\{1,2\}' /proc/cpuinfo

grep --color '\<[0-9]\{1,2\}\>' /proc/cpuinfo

 

2、找出ifconfig命令结果中的1-255之间的整数;

需要使用扩展正则表达式

ifconfig | egrep --color '\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-9][0-9])\>'

 

3、查找当前系统上名字为student(必须出现在行首)的用户的帐号的相关信息, 文件为/etc/passwd

grep '^student\>' /etc/passwd | cut -d: -f3

id -u student

 

student1

student2

 

练习:

分析/etc/inittab文件中如下文本中前两行的特征(每一行中出现在数字必须相同),请写出可以精确找到类似两行的模式:

l1:1:wait:/etc/rc.d/rc 1

l3:3:wait:/etc/rc.d/rc 3

 

grep '^l\([0-9]\):\1.*\1$' /etc/inittab

 

 

05_01_egrep及扩展正则表达式



复习:

REGEXP:REGular EXPression

Pattern:模式

 

正则表达式:

         Basic REGEXP:基本

         Extended REGEXP:扩展

 

基本正则表达式:

.:

[]:

[^]:

 

次数匹配:

*:

\?: 0或1次

\{m,n\}:至少m次,至多n次;

 

.*:

 

锚定:

^:

$:

\<, \b:

\>, \b:

 

\(\)

\1, \2, \3, ...

 

grep:使用基本正则表达式定义的模式来过滤文本的命令;

         -i

         -v

         -o

         --color

         -E: 使用扩展正则表达式

         -A n: 显示匹配到的行和其后的n行

         -B n: 前的n行

         -C n: 前后各n行

        

扩展正则表达式:省略很多反斜线

 

字符匹配:

.

[]

[^]

 

次数匹配:

*:

?: 

+: 匹配其前面的字符至少1次,\{1,\}

{m,n}: 

 

位置锚定:

^

$

\<

\>

 

分组:

():分组

\1, \2, \3, ...

 

或者

|: or

C|cat:  C或cat, 不是Cat或cat,这个用 '(C|c)at'

 

grep -E = egrep

 

4、显示所有以数字结尾且文件名中不包含空白的文件;

 bash特性详解时的未解问题

ls .*[^[[:space:]].*[0-9]$

 

找出/boot/grub/grub.conf文件中1-255之间的数字;

\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>

 

找出ifconfig中的IP地址 

ifconfig | egrep '\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>'

 

ifconfig | egrep --color '(\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.){3}\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>'

 

找出ifconfig中的ABC 3IP地址 

IPv4:

5类:A B C D E

A:1-127

B:128-191

C:192-223

 

\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[01][0-9]|22[0-3])\>(\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>){2}\.\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>

 

 

马哥51cto博客: http://mageedu.blog.51cto.com/

 

fgrep: 快速grep, 不支持正则表达式

第八章、bash脚本编程(上)



05_02_bash脚本编程之一变量、变量类型等



shell编程: 脚本编程

 

语言转换器:编译器,解释器

 

编程语言:机器语言、汇编语言、高级语言

 

静态语言:编译型语言

         特点:强类型(变量)

                     事先转换成可执行格式

         包括:C、C++、JAVA、C#

        

动态语言:解释型语言, on the fly

         特点:弱类型

                   边解释边执行

         包括:PHP、SHELL、python、perl

 

面向过程:Shell, C

面向对象: JAVA, Python, perl, C++

 

变量:内存空间,命名

内存:编址的存储单元

 

变量类型:事先确定数据的存储格式和长度

         字符

         数值

                   整型

                   浮点型: 11.23, 1.123*10^1, 0.1123*10^2



存储日期:         

字符:2013/10/10 -  64bit

数值: 99999 - 24bit,



        布尔:真、假    

        

逻辑:1+1>2

逻辑运算:与、或、非、异或

1: 真

0: 假

 

1 & 0  = 0

0 & 1 = 0

0 & 0 = 0

1 & 1 = 1

 

或:

 

非:

! 真 = 假

! 假 = 真



异或:相异为1,相同为0

 

shell: 弱类型编程语言

 

强类型,弱类型的特点:

强:变量在使用前,必须事先声明,甚至还需要初始化;

弱:变量用时声明,甚至不区分类型;

 

变量赋值:VAR_NAME=VALUE

 

bash变量类型:

         环境变量

         本地变量(局部变量)

         位置变量

         特殊变量

        

1. 本地变量: VARNAME=VALUE: 作用域为整个bash进程;set 可以省略

2. 局部变量:local VARNAME=VALUE:作用域为当前代码段;

3. 环境变量:作用域为当前shell进程及其子进程;

                export VARNAME=VALUE

                或 

                VARNAME=VALUE; export VARNAME

                 export:“导出”

                export PATH=$PATH:/usr/local/mypath

 

4. 位置变量:$1, $2, ...

5. 特殊变量:$?: 上一个命令的执行状态返回值;

 

程序执行,可能有两类返回值:

         1. 程序执行结果

         2. 程序状态返回代码(0-255)

                   0: 正确执行

                   1-255:错误执行,1,2,127系统预留;

                  

输出重定向:

>  覆盖重定向

>>  追加重定向

2>  错误重定向   

2>>错误追加重定向

&> 同时重定向

 

/dev/null: 软件设备, bit bucket,数据黑洞    



撤消变量:

unset VARNAME

 

查看当shell中变量:

set:包括本地变量和环境变量

 

查看当前shell中的环境变量:

printenv

env

export

 

脚本:命令的堆砌,按实际需要,结合命令流程控制机制实现的源程序

 

脚本的特殊标记:

shebang: 魔数

#!/bin/bash

# 注释行,不执行

        

脚本在执行时会启动一个子shell进程;

         1. 命令行中启动的脚本会继承当前shell环境变量;

         2. 系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量;

        

        

05_03_bash脚本编程之二    条件判断



练习:写一个脚本,完成以下任务 - 答案为addusers.sh

1、添加5个用户, user1,..., user5

2、每个用户的密码同用户名,而且要求,添加密码完成后不显示passwd命令的执行结果信息;

3、每个用户添加完成后,都要显示用户某某已经成功添加;

#!/bin/bash

useradd user1

echo "user1" | passwd --stdin user1 &> /dev/null

echo "Add user1 successfully."

 

条件判断:

         如果用户不存在

                   添加用户,给密码并显示添加成功;

         否则

                   显示如果已经没在,没有添加;

 

bash中如何实现条件判断?

条件测试类型:

         整数测试

         字符测试

         文件测试

 

条件测试的表达式:

         [ expression ] : 中括号和expression之间必须有空格

         ` expression `

         test expression

        

整数比较:

         -eq: 测试两个整数是否相等;比如 $A -eq $B

         -ne: 测试两个整数是否不等;不等,为真;相等,为假;

         -gt: 测试一个数是否大于另一个数;大于,为真;否则,为假;

         -lt: 测试一个数是否小于另一个数;小于,为真;否则,为假;

         -ge: 大于或等于

         -le:小于或等于

        

命令间的逻辑关系:

         逻辑与: &&

                   第一个条件为假时,第二条件不用再判断,最终结果已经有;

                   第一个条件为真时,第二条件必须得判断;

         逻辑或: ||

        

如果用户user6不存在,就添加用户user6

! id user6 && useradd user6

id user6 || useradd user6

 

如果/etc/inittab文件的行数大于100,就显示好大的文件;

[ `wc -l /etc/inittab | cut -d' ' -f1` -gt 100 ] && echo "Large file."

 

变量名称:

         1、只能包含字母、数字和下划线,并且不能数字开头;

         2、不应该跟系统中已有的环境变量重名;

         3、最好做到见名知义;

 

如果用户存在,就显示用户已存在;否则,就添加此用户;

id user1 && echo "user1 exists." || useradd user1

 

如果用户不存在,就添加;否则,显示其已经存在;

! id user1 && useradd user1 || echo "user1 exists."

 

如果用户不存在,添加并且给密码;否则,显示其已经存在;

! id user1 && useradd user1 && echo "user1" | passwd --stdin user1|| echo "user1 exists."

 

 

练习,写一个脚本,完成以下要求: - 答案为adduser2.sh文件

1、添加3个用户user1, user2, user3;但要先判断用户是否存在,不存在而后再添加;

2、添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;

3、最后显示当前系统上共有多少个用户;

 

 

练习,写一个脚本,完成以下要求: - 答案为third.sh文件 

给定一个用户:

         1、如果其UID为0,就显示此为管理员;

         2、否则,就显示其为普通用户;

 

使用if语句:

如果 UID为0;那么

  显示为管理员

否则

  显示为普通用户

 

NAME=user16

USERID=`id -u $NAME`

if [ $USERID -eq 0 ]; then

  echo "Admin"

else

  echo "common user."

fi

 

NAME=user16

if [ `id -u $NAME` -eq 0 ]; then

  echo "Admin"

else

  echo "common user."

fi

 

 

 

05_04_bash脚本编程之三条件判断及算术运算



1. 练习:写一个脚本  - 答案为 bash.sh

判断当前系统上是否有用户的默认shell为bash;

   如果有,就显示有多少个这类用户;否则,就显示没有这类用户;

grep "bash$" /etc/passwd &> /dev/null

RETVAL=$?

if [ $RETVAL -eq 0 ]; then

  

if grep "bash$" /etc/passwd &> /dev/null; then

        

提示:“引用”一个命令的执行结果,要使用命令引用;比如: RESAULTS=`wc -l /etc/passwd | cut -d: -f1`;

      使用一个命令的执行状态结果,要直接执行此命令,一定不能引用;比如: if id user1一句中的id命令就一定不能加引号;

           如果想把一个命令的执行结果赋值给某变量,要使用命令引用,比如USERID=`id -u user1`;

      如果想把一个命令的执行状态结果保存下来,并作为命令执行成功与否的判断条件,则需要先执行此命令,而后引用其状态结果,如

                   id -u user1

                   RETVAL=$?

                   此句绝对不可以写为RETVAL=`id -u user1`;

        

        

2. 练习:写一个脚本  - 答案为bash2.sh

判断当前系统上是否有用户的默认shell为bash;

   如果有,就显示其中一个的用户名;否则,就显示没有这类用户;

 

3. 练习:写一个脚本

给定一个文件,比如/etc/inittab

判断这个文件中是否有空白行;

如果有,则显示其空白行数;否则,显示没有空白行。

                                      

1

2

3

4

5

6

7

8

9

10

11

12

#!/bin/bash

FILE=/etc/inittab

if [ ! -e $FILE ]; then

  echo "No $FILE."

  exit 8

fi

  

if grep "^$" $FILE &> /dev/null; then

  echo "Total blank lines: `grep "^$" $FILE | wc -l`."

else

  echo "No blank line."

fi

 

 

4. 练习:写一个脚本

给定一个用户,判断其UID与GID是否一样

如果一样,就显示此用户为“good guy”;否则,就显示此用户为“bad guy”。

1

2

3

4

5

6

7

8

9

#!/bin/bash

USERNAME=user1

USERID=`id -u $USERNAME`

GROUPID=`id -g $USERNAME`

if [ $USERID -eq $GROUPID ]; then

  echo "Good guy."

else

  echo "Bad guy."

fi

 

 

进一步要求:不使用id命令获得其id号;

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#!/bin/bash

#

USERNAME=user1

if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then

  echo "No such user: $USERNAME."

  exit 1

fi

  

USERID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f3`

GROUPID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f4`

if [ $USERID -eq $GROUPID ]; then

  echo "Good guy."

else

  echo "Bad guy."

fi

 

 

5. 练习:写一个脚本

给定一个用户,获取其密码警告期限;

而后判断用户密码使用期限是否已经小于警告期限;

         提示:计算方法,最长使用期限减去已经使用的天数即为剩余使用期限;

        

如果小于,则显示“Warning”;否则,就显示“OK”。

 

圆整:丢弃小数点后的所有内容

 

1

2

3

4

5

6

7

8

9

10

11

12

13

#!/bin/bash

W=`grep "student" /etc/shadow | cut -d: -f6`

S=`date +%s`

T=`expr $S/86400`

L=`grep "^student" /etc/shadow | cut -d: -f5`

N=`grep "^student" /etc/shadow | cut -d: -f3`

SY=$[$L-$[$T-$N]]

  

if [ $SY -lt $W ]; then

  echo 'Warning'

else

  echo 'OK'

fi

 

6. 练习:写一个脚本

判定命令历史中历史命令的总条目是否大于1000;如果大于,则显示“Some command will gone.”;否则显示“OK”。

 history | tail -1 | cut -d' ' -f1

需要去掉开头的空格,cut 无法解决,留疑

 

shell中如何进行算术运算:

A=3

B=6

1、let 算术运算表达式

         let C=$A+$B

2、$[算术运算表达式]

         C=$[$A+$B]

3、$((算术运算表达式))

         C=$(($A+$B))

4、expr 算术运算表达式,表达式中各操作数及运算符之间要有空格,而且要使用命令引用

         C=`expr $A + $B`

 

条件判断,控制结构:

1. 单分支if语句

if 判断条件; then

  statement1

  statement2

  ...

fi

 

2. 双分支的if语句:

if 判断条件; then

         statement1

         statement2

         ...

else

         statement3

         statement4

         ...

fi

 

3. 多分支的if语句:

if 判断条件1; then

  statement1

  ...

elif 判断条件2; then

  statement2

  ...

elif 判断条件3; then

  statement3

  ...

else

  statement4

  ...

fi





06_01_bash脚本编程之四整数测试及特殊变量

     

 

复习:

测试方法:

[ expression ]

` expression `

test expression

 

bash中常用的条件测试有三种:整数,字符串,文件

整数测试:

 -gt

 -le

 -ne

 -eq

 -ge

 -lt

 

INT1=63

INT2=77

[ $INT1 -eq $INI2 ]

[[ $INT1 -eq $INT2 ]]

test $INT1 -eq $INT2 

 

文件测试:    

-e FILE:测试文件是否存在,exist的简写

-f FILE: 测试文件是否为普通文件

-d FILE: 测试指定路径是否为目录

-r FILE: 测试当前用户对指定文件是否有读取权限;

-w FILE:   ~写权限

-x FILE:    ~执行

 

e.g: 

[ -e /etc/inittab ]

[ -x /etc/rc.d/rc.sysinit ] 

 

练习:写一个脚本 - 答案为filetest2.sh

给定一个文件:

如果是一个普通文件,就显示之;

如果是一个目录,亦显示之;

否则,此为无法识别之文件;

 

定义脚本退出状态码

exit: 退出脚本

exit #

如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码;

 

测试脚本是否有语法错误:

bash -n 脚本

 

调试脚本:

bash -x 脚本:打印每步执行

 

bash变量的类型:

         本地变量(局部变量)

         环境变量

         位置变量:

                   $1, $2, ...

                   shift [n]:移出前面的n(默认为1)个参数,后面的参数向前移

         特殊变量:

                   $?

                   $#:参数的个数

                   $*: 参数列表

                   $@:参数列表

    

e.g:     

./filetest.sh /etc/fstab /etc/inittab

$1: /etc/fstab

$2: /etc/inittab

 

练习:写一脚本 - 答案为 filetest3.sh

能接受一个参数(文件路径)

判定:此参数如果是一个存在的文件,就显示“OK.”;否则就显示"No such file."

 

练习:写一个脚本 - 答案为 cacl.sh

给脚本传递两个参数(整数);

显示此两者之和,之乘积;

#!/bin/bash

#

if [ $# -lt 2 ]; then

  echo "Usage: cacl.sh ARG1 ARG2"

  exit 8

fi

 

echo "The sum is: $[$1+$2]."

echo "The prod is: $[$1*$2]."

 

练习:写一个脚本,完成以下任务

1、使用一个变量保存一个用户名;

2、删除此变量中的用户,且一并删除其家目录;

3、显示“用户删除完成”类的信息;

 #!/bin/bash

#

USER=user1

if userdel -r $USER; then

    echo "Delete user finished."

else

    echo "Delete user failed."

fi

 

 

06_03_bash脚本编程之五字符串测试及for循环

        

shell编程引用变量:${VARNAME}, 括号有时可省略。

 

1. 练习: - 答案为testuser.sh

传递一个用户名参数给脚本,判断此用户的用户名跟其基本组的组名是否一致,并将结果显示出来。

#!/bin/bash

if [ 'id -nu $1' == 'id -gu $1' ]; then

fi 



字符串测试:符号两端要有空格

==:测试是否相等,相等为真,不等为假

!=:测试是否不等,不等为真,等为假

>:一般不用

< :一般不用

-z string: 测试指定字符串是否为空,空则真,不空则假

-n string: 测试指定字符串是否不空,不空为真,空则为假

 

2. 练习:写一个脚本

传递一个参数(单字符就行)给脚本,如参数为q,就退出脚本;否则,就显示用户的参数;

 

3. 练习:写一个脚本

传递一个参数(单字符就行)给脚本,如参数为q、Q、quit或Quit,就退出脚本;否则,就显示用户的参数;

#!/bin/bash

if [ $1 = 'q' ];then

  echo "Quiting..."

  exit 1

elif [ $1 = 'Q' ];then

  echo "Quiting..."

  exit 2 

elif [ $1 = 'quit' ];then

  echo "Quiting..."

  exit 3

elif [ $1 = 'Quit' ];then

  echo "Quiting..."

  exit 4 

else

  echo $1

fi

 

4. 练习:

传递三个参数给脚本,第一个为整数,第二个为算术运算符,第三个为整数,将计算结果显示出来,要求保留两位精度。形如:

./calc.sh 5 / 2

提示:

scale=2保留两位精度

echo "scale=2;111/22;" | bc

bc <<< "scale=2;111/22;" 



#!/bin/bash

if [ $# -lt 3 ]; then 

    echo "Usage: `basename $0` num1 opt num2"

    exit 1

fi

bc <<< "scale=2;$1 $2 $3"



5. 练习:

传递3个参数给脚本,参数均为用户名。将此些用户的帐号信息提取出来后放置于/tmp/testusers.txt文件中,并要求每一行行首有行号。

        

6. 练习,写一个脚本:

判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor_id一行中。

如果其生产商为AuthenticAMD,就显示其为AMD公司;

如果其生产商为GenuineIntel,就显示其为Intel公司;

否则,就说其为非主流公司;



#!/bin/bash

VENDOR_ID=`grep vendor_id /proc/cpuinfo | head -1 | cut -d' ' -f2` 

if [ $VENDOR_ID == "AuthenticAMD" ]; then

    echo "AMD company"

elif [ $VENDOR_ID == "GenuineIntel" ]; then

    echo "Intel company"

fi



7. 练习,写一个脚本:

给脚本传递三个整数,判断其中的最大数和最小数,并显示出来。

MAX=0

MAX -eq $1

MAX=$1

MAX -lt $2

MAX=$2

 

 

循环:一定要有:进入条件,退出条件

1. for

2. while

3. until

 

for循环语句

for 变量 in 列表; do

  循环体

done



列表遍历完成之后,退出; 



e.g:

for I in 1 2 3 4 5 6 7 8 9 10; do

  加法运算

done

 

如何生成列表:

1. {1..100}

2. seq命令:`seq [起始数 [步进长度]] 结束数`,

 

8. 练习:求1-100的和 - 答案为sum.sh

 

declare: 

         -i: 将一个变量声明为整型,integer

         -x: 将一个变量声明为环境变量

e.g: declare -i SUM=0



9. 写一个脚本:

1、设定变量FILE的值为/etc/passwd

2、依次向/etc/passwd中的每个用户问好,并显示对方的shell,形如: 

         Hello, root, your shell: /bin/bash

3、统计一共有多少个用户

 

for I in `seq 1 $LINES`; do echo "Hello, `head -n $I /etc/passwd | tail -1 | cut -d: -f1`"; done

 

只向默认shell为bash的用户问声好

第八章、bash脚本编程(中)

 

07_02_bash脚本编程之六使用脚本选项及组合条件测试(39 - $

 

10. 写一个脚本: 

1、添加10个用户user1到user10,密码同用户名;但要求只有用户不存在的情况下才能添加;

 

2. 扩展: - 答案为adminusers.sh

接受一个参数:

add: 添加用户user1..user10

del: 删除用户user1..user10

其它:退出



3. 参数指定 添加/删除 多个用户 - 答案为adminusers2.sh

adminusers --add user1,user2,user3,hello,hi

 

11. 写一个脚本:

计算100以内所有能被3整除的正整数的和;

取模,取余:%

3%2=1

100%55=45

 

12. 写一个脚本:

计算100以内所有奇数的和以及所有偶数的和;分别显示之;

 

let I=$[$I+1]

SUM=$[$SUM+$I]

 

let SUM+=$I

 

let I+=1 相当于 let I++

 

-=

         let I-=1 相当于 let I--

        

         ++I, --I

 

*=

/=

%=

 

13. 写一个脚本:

分别显示当前系统上所有默认shell为bash的用户和默认shell为/sbin/nologin的用户,并统计各类shell下的用户总数。显示结果形如:

BASH,3users,they are:

root,redhat,gentoo

 

NOLOGIN, 2users, they are:

bin,ftp

 

 

#!/bin/bash

#

NUMBASH=`grep "bash$" /etc/passwd | wc -l`

BASHUSERS=`grep "bash$" /etc/passwd | cut -d: -f1`

BASHUSERS=`echo $BASHUSERS | sed 's@[[:space:]]@,@g'`

 

echo "BASH, $NUMBASH users, they are:"

echo "$BASHUSERS

 

组合测试条件

         -a: 与关系

         -o: 或关系

          !:非关系

        

if [ $# -gt 1 -a $# -le 3 ]

if [ $# -gt 1 ] && [ $# -le 3 ]

 

练习: - 答案为 quit.sh

判断参数是不是在:q, Q, quit, Quit中。

 

 

08_01_facl及用户及Linux终端(65 - $



生成随机数

RANDOM 系统内置环境变量可以生成随机数,范围: 0-32768

 

随机数生成器:熵池,保存很多随机数,可能取空

/dev/random: 熵池空时,阻塞,更安全

/dev/urandom: 熵池空时,软件模拟生成,





08_02_bash脚本编程之七 case语句及脚本选项进阶



练习:

写一个脚本,利用RANDOM生成10个随机数,并找出其中的最大值,和最小值;答案为random.sh

#!/bin/bash

#

declare -i MAX=0

declare -i MIN=0

 

for I in {1..10}; do

  MYRAND=$RANDOM

  [ $I -eq 1 ] && MIN=$MYRAND

  if [ $I -le 9 ]; then

    echo -n "$MYRAND,"

  else

    echo "$MYRAND"

  fi

  [ $MYRAND -gt $MAX ] && MAX=$MYRAND

  [ $MYRAND -lt $MIN ] && MIN=$MYRAND

done

 

echo $MAX, $MIN

 

#!/bin/bash

#

for i in {1..10}; do

    NUMS+=$RANDOM" "

done



MAXNUM=`echo $NUMS | cut -d' ' -f1`

MINNUM=$MAXNUM



for i in $NUMS; do

    [ $i -gt $MAXNUM ] && MAXNUM=$i 

    [ $i -lt $MINNUM ] && MINNUM=$i 

done



echo $NUMS

echo "max: $MAXNUM"

echo "min: $MINNUM"

 

 

 

面向过程的控制结构包括:

                   顺序结构

                   选择结构

                   循环结构

 

选择结构:ficase语句

if: 单分支、双分支、多分支

if CONDITION; then

  statement

  ...

fi

 

if CONDITION; then

  statement

  ...

else

  statement

  ...

fi

 

if CONDITION1; then

  statement

  ...

elif CONDITION2; then

  statement

  ...

esle

  statement

  ...

fi

 

case语句:选择结构

 

case SWITCH in

value1)

  statement

  ...

  ;;

value2)

  statement

  ...

  ;;

*)

  statement

  ...

  ;;

esac

 

value可以使用: - 例如case.sh

a-z

A-Z

0-9

[abc]

 

debug.sh练习case的使用

 

练习:写一个脚本,实现功能:添加删除用户,显示详细信息 - 答案为adminusers3.sh

#!/bin/bash

#

DEBUG=0

ADD=0

DEL=0

 

for I in `seq 0 $#`; do

  if [ $# -gt 0 ]; then

           case $1 in

           -v|--verbose)

                   DEBUG=1

                   shift ;;

           -h|--help)

                   echo "Usage: `basename $0` --add USER_LIST --del USER_LIST -v|--verbose -h|--help"

                   exit 0

                   ;;

           --add)

                   ADD=1

                   ADDUSERS=$2

                   shift 2

                   ;;

           --del)

                   DEL=1

                   DELUSERS=$2

                   shift 2

                   ;;

           *)

                   echo "Usage: `basename $0` --add USER_LIST --del USER_LIST -v|--verbose -h|--help"

                   exit 7

                   ;;

    esac

  fi

done

 

if [ $ADD -eq 1 ]; then

  for USER in `echo $ADDUSERS | sed 's@,@ @g'`; do

    if id $USER &> /dev/null; then

      [ $DEBUG -eq 1 ] && echo "$USER exists."

    else

      useradd $USER

      [ $DEBUG -eq 1 ] && echo "Add user $USER finished."

    fi

  done

fi

 

if [ $DEL -eq 1 ]; then

  for USER in `echo $DELUSERS | sed 's@,@ @g'`; do

    if id $USER &> /dev/null; then

      userdel -r $USER

      [ $DEBUG -eq 1 ] && echo "Delete $USER finished."

    else

      [ $DEBUG -eq 1 ] && echo "$USER not exist."

    fi

  done

fi

 

 

08_03_磁盘及文件系统管理详解之一(^-15



练习:写一个脚本showlogged.sh,其用法格式为:

showlogged.sh -v -c -h|--help

其中,-h选项只能单独使用,用于显示帮助信息;-c选项时,显示当前系统上登录的所有用户数;如果同时使用了-v选项,则既显示同时登录的用户数,又显示登录的用户的相关信息;如 

Logged users: 4.

 

They are:

root     tty2         Feb 18 02:41

root     pts/1        Mar  8 08:36 (172.16.100.177)

root     pts/5        Mar  8 07:56 (172.16.100.177)

hadoop   pts/6        Mar  8 09:16 (172.16.100.177)

 

#!/bin/bash

#

declare -i SHOWNUM=0

declare -i SHOWUSERS=0

 

for I in `seq 1 $#`; do

  if [ $# -gt 0 ]; then

    case $1 in

    -h|--help)

      echo "Usage: `basename $0` -h|--help -c|--count -v|--verbose"

      exit 0 ;;

    -v|--verbose)

      let SHOWUSERS=1

      shift ;;

    -c|--count)

      let SHOWNUM=1

      shift ;;

    *)

      echo "Usage: `basename $0` -h|--help -c|--count -v|--verbose"

      exit 8 ;;

    esac

  fi

done

 

if [ $SHOWNUM -eq 1 ]; then

  echo "Logged users: `who | wc -l`."

  if [ $SHOWUSERS -eq 1 ]; then

    echo "They are:"

    who

  fi

fi

 

 

终端类型:

         console: 控制台

         pty: 物理终端 (VGA)

         tty#: 虚拟终端 (VGA)

         ttyS#: 串行终端

         pts/#: 伪终端

        

 

 

练习:写一个脚本

通过命令行传递一个文件路径参数给脚本:

         如果参数多了或少了,报错;

         如果参数指定的路径对应的是目录而不是文件,报错;

而后,检查路径指定的文件是否为空或不存在,如果是,则新建此文件,并在文件中生成如下内容

#!/bin/bash

#

而后,使用vim编辑器打开此文件,并让光标处于这个文件的最后一行;

 #!/bin/bash

if [ ! $# -eq 1 ]; then

    echo "Usage: `basename $0` filepath"

    exit 1

fi

if [ -d $1 ]; then

    echo $?

    echo "The file path is directory!"

    exit 2

fi

if [ ! -e $1 ]; then

    echo -e "#!/bin/bash\n#" > $1

    vim $1

    exit 3

fi

if grep "[^[:space:]]" $1 &>/dev/null; then

    vim + $1

    exit 4

else

    echo -e "#!/bin/bash\n#" > $1

    vim $1

    exit 3

fi

 

 

写个脚本,按如下方式执行:

mkscript.sh -v|--version VERSION -a|--author AUTHOR -t|--time DATETIME -d|--description DESCRIPTION -f|--file /PATH/TO/FILE -h|--help

 

1、此脚本能创建或打开-f选项指向的文件/PATH/TO/FILE;如果其为空文件,能自动为其生成第一行;如果文件不空,且第一行不是#!/bin/bash,则中止此脚本,并报错“The file is not a bash script.";否则,则直接使用vim 打开此文件;

提示:/PATH/TO/FILE,要判断其目录是否存在;如果不存在,则报错;

 

2、如果为空文件,自动生成的第一行内容为:

#!/bin/bash

3、如果为空文件,且使用了-a选项,则在文件中添加“# Author: -a选项的参数”,比如:

# Author: Jerry

4、如果为空文件,且使用了-t选项,则在文件中添加“# Date: 脚本执行-t选项后指定的时间”,比如:

# Date: 2013-03-08 18:05

5、如果为空文件,且使用了-d选项,则在文件中添加“# Description: -d选项的内容”,比如:

# Description: Create a bash script file head.

6、如果为空文件,且使用了-v选项,则在文件添加“# Version: -v后跟的参数”,比如:

# Version: 0.1

7、-h选项只能单独使用,用于显示使用帮助;

8、其它选项,显示帮助信息;

 

说明:

这是一个用于创建脚本的脚本,它可以自动帮助创建一个bash脚本的文件头,这样,以后使用此脚本来创建其它脚本将变得比较高效。比如:

#!/bin/bash

# Author: Jerry([email protected])

# Date: 2013-03-08 18:05

# Description: Create a bash script file head.

# Version: 0.1

#

 

 

 #!/bin/bash

#

print_help()

{

    echo "Usage: `basename $0` [options]"

    echo "Options:"

    echo -e "\t -t|--time"

    echo -e "\t -a|--author AUTHOR"

    echo -e "\t -v|--version VERSION"

    echo -e "\t -f|--file /PATH/TO/FILE"

    echo -e "\t -d|--description DESCRIPTION"

    echo -e "\t -h|--help"

    exit 1

}

[ $# -eq 0 ] && print_help

while [ $# -gt 0 ]; do

    case $1 in

        -f|--file)

        FILE=$2

        shift 2;;

        -a|--author)

        AUTHOR=$2

        shift 2;;

        -t|--time)

        DATE=`date "+%F %T"`

        shift;;

        -d|--description)

        DESCRIPTION=$2

        shift 2;;

        -v|--version)

        VERSION=$2

        shift 2;;

        -h|--help)

        print_help

        exit 1;;

        *)

        print_help

        exit 1;;

    esac

done

if [ -f $FILE ]; then

    if grep "[^[:space:]]" $FILE &>/dev/null; then

        if [ `head -1 $FILE` != "#!/bin/bash" ]; then

            echo "The file is not a bash script."

            exit 3

        else

            vim + $FILE

            exit 2

        fi

    fi

fi

if [ -d $FILE ]; then

    echo "$FILE is a directory."

    exit 3

fi

echo "#!/bin/bash" >> $FILE

[ -n "$AUTHOR" ] && echo "# Author: $AUTHOR" >> $FILE

[ -n "$DATE" ] && echo "# Date: $DATE" >> $FILE

[ -n "$DESCRIPTION" ] && echo "# Description: $DESCRIPTION" >> $FILE

[ -n "$VERSION" ] && echo "# Version: $VERSION" >> $FILE

echo "#" >> $FILE

vim + $FILE

 

 

 

 

bss: Block Started by Symbol

 

readelf -h

readelf -S

objdump -h

 

ELF魔数、文件机器字节长度、数据存储方式、版本、运行平台、ABI版本、ELF重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口和长度、段表的位置和长度、段的数量。



09_04_Linux压缩及归档 (66分钟-$)

脚本编程3种控制结构:

         1. 顺序结构

         2. 选择结构

                   if

                   case

         3. 循环结构

                   for

                   while

                   until

                  

while循环:适用于循环次数未知的场景,要有退出条件

语法:

         while CONDITION; do

           statement

           ...

         done

        

练习:计算100以内所有正整数的和

 

#!/bin/bash

declare -i I=1

declare -i SUM=0

 

while [ $I -le 100 ]; do

  let SUM+=$I

  let I++

done

 

echo $SUM

 

练习:转换用户输入的字符为大写,除了quit:

#!/bin/bash

#

read -p "Input something: " STRING

 

while [ $STRING != 'quit' ]; do

  echo $STRING | tr 'a-z' 'A-Z'

  read -p "Input something: " STRING

done

 

练习:每隔5秒查看hadoop用户是否登录,如果登录,显示其登录并退出;否则,显示当前时间,并说明hadoop尚未登录:

#!/bin/bash

#

who | grep "hadoop" &> /dev/null

RETVAL=$?

 

while [ $RETVAL -ne 0 ]; do

  echo "`date`, hadoop is not log."

  sleep 5

  who | grep "hadoop" &> /dev/null

  RETVAL=$?

done

 

echo "hadoop is logged in."

 

 

10_01_Raidmdadm命令之一 (^ - 17)



写一个脚本:

1) 显示一个菜单给用户:

d|D) show disk usages.

m|M) show memory usages.

s|S) show swap usages.

*) quit.

2) 当用户给定选项后显示相应的内容;

  

扩展:

         当用户选择完成,显示相应信息后,不退出;而让用户再一次选择,再次显示相应内容;除了用户使用quit;



#!/bin/bash

#

cat << EOF

d|D) show disk usages.

m|M) show memory usages.

s|S) show swap usages.

*) quit.

EOF

 

read -p "Your choice: " CHOICE

while [ $CHOICE != 'quit' ];do

  case $CHOICE in

  d|D)

    echo "Disk usage: "

    df -Ph ;;

  m|M)

    echo "Memory usage: "

    free -m | grep "Mem" ;;

  s|S)

    echo "Swap usage: "

    free -m | grep "Swap" ;;

  *)

    echo "Unknown.." ;;

  esac

 

read -p "Again, your choice: " CHOICE

done        

 

控制echo显示文字的颜色以及显示效果

echo -e "\033[1;31;41mHello\033[0m,world"

[31m: 两位数字控制颜色,第一位表示控制前/背景色,3-前景色,4-背景色,

[1m: 一位数字控制字体,加粗,闪烁,下划线等,1为加粗

\033 - ctrl键



echo显示字体颜色  http://blog.chinaunix.net/uid-8504518-id-2030688.html

 

第九章、sed 命令



06_02_sed命令



Linux三大文本处理工具:grep, sed(流编辑器), awk     

 

sed基本用法:

sed: Stream EDitor

         行编辑器 (全屏编辑器: vi),逐行读取

 

sed: 模式空间

默认不编辑原文件,仅对模式空间中的数据做处理;而后,处理结束后,将模式空间打印至屏幕;

 

sed [options] 'AddressCommand' file ...

         -n: 静默模式,不再默认显示模式空间中的内容

         -i: 直接修改原文件

         -e SCRIPT -e SCRIPT:可以同时执行多个脚本

         -f /PATH/TO/SED_SCRIPT: 从文件中读取命令,把命令写入文件,不需要单引号括起来

                   sed -f /path/to/scripts  file

         -r: 表示使用扩展正则表达式

        

Address:

1、StartLine,EndLine

         比如1,100

         $:最后一行

2、/RegExp/

         /^root/

3、/pattern1/,/pattern2/

         第一次被pattern1匹配到的行开始,至第一次被pattern2匹配到的行结束,这中间的所有行

4、LineNumber

         指定的行

5、StartLine, +N

         从startLine开始,向后的N+1行;

        

Command:

         d: 删除符合条件的行;

         p: 显示符合条件的行;

         a \string: 在指定的行后面追加新行,内容为string

                   \n:可以用于换行

         i \string: 在指定的行前面添加新行,内容为string

         r FILE: 将指定的文件的内容添加至符合条件的行处

         w FILE: 将地址指定的范围内的行另存至指定的文件中;

         s/pattern/string/修饰符: 查找并替换,默认只替换每行中第一次被模式匹配到的字符串

                   匹配多个字符串,需要加修饰符: 

                       g: 全局替换

                       i: 忽略字符大小写

             s///: 也可以使用其他字符做分隔符,只要一样就行,如s###, s@@@ 

       

         

 后项引用: \(\), \1, \2

                   &: 引用模式匹配整个串



   l..e->l..er: like-->liker

                      love-->lover

     sed 's#\(l..e\)#\1r#g'

     sed 's#l..e#&r#g'

                    

     l..e->L..e:    like-->Like

                         love-->Love

        sed 's#l\(..e\)#L\1#g'

        

 

sed练习:

1、删除/etc/grub.conf文件中行首的空白符;

sed -r 's@^[[:spapce:]]+@@g' /etc/grub.conf 

sed 's/^\ \+//' /etc/grub.conf

2、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5;

sed 's@\(id:\)[0-9]\(:initdefault:\)@\15\2@g' /etc/inittab

sed -r 's@(id:)[0-9](:initdefault:)@\15\2@g' /etc/inittab

3、删除/etc/inittab文件中的空白行;

sed '/^$/d' /etc/inittab

4、删除/etc/inittab文件中开头的#号;

sed 's@^#@@g' /etc/inittab

5、删除某文件中开头的#号及后面的空白字符,但要求#号后面必须有空白字符;

sed -r 's@^#[[:space:]]+@@g' /etc/inittab

6、删除某文件中以空白字符后面跟#类的行中的开头的空白字符及#

sed -r 's@^[[:space:]]+#@@g' /etc/inittab

sed 's/^\ \+#//' /etc/inittab

7、取出一个文件路径的目录名称;

echo "/etc/rc.d/" | sed -r 's@^(/.*/)[^/]+/?@\1@g'     

    取出基名:

        echo "/etc/rc.d/" | sed -r 's@^/.*/([^/]+)/?@\1@g'     

 第十章、vim编辑器详解



07_01_vim编辑器详解



vim编辑器:文本编辑器,字处理器,处理ASCII

 

其他编辑器:nano, sed

 

vi: Visual Interface

vim: VI iMproved

 

vi特点:全屏编辑器,模式化编辑器

 

vim模式:

编辑模式(命令模式)

输入模式

末行模式

 

模式转换:

编辑-->输入:

         i: 在当前光标所在字符的前面,转为输入模式;

         a: 在当前光标所在字符的后面,转为输入模式;

         o: 在当前光标所在行的下方,新建一行,并转为输入模式;

        

         I:在当前光标所在行的行首,转换为输入模式

        A:在当前光标所在行的行尾,转换为输入模式

        O:在当前光标所在行的上方,新建一行,并转为输入模式;

 

输入-->编辑:  ESC

编辑-->末行:”:“

末行-->编辑:  ESC, ESC

 

一、打开文件

# vim /path/to/somefile

         vim +# :打开文件,并定位于第#行

         vim +:打开文件,定位至最后一行

         vim +/PATTERN : 打开文件,定位至第一次被PATTERN匹配到的行的行首

 

         打开文件后默认处于编辑模式

        

二、关闭文件

1、末行模式关闭文件

    :q  退出

    :wq 保存并退出

    :q! 不保存并退出

    :w 保存

    :w! 强行保存

    :wq --> :x

    :x 如果文件没有修改,直接退出;如果有修改,则保存后退出



2、编辑模式下退出

    ZZ: 保存并退出

 

三、移动光标(编辑模式)

1、逐字符移动:

         h: 左

         l: 右

         j: 下

         k: 上

 #h: 移动#个字符;

 

2、以单词为单位移动

         w: 移至下一个单词的词首

         e: 跳至当前或下一个单词的词尾

         b: 跳至当前或前一个单词的词首

        

         #w:

        

3、行内跳转:

         0: 绝对行首

         ^: 行首的第一个非空白字符

         $: 绝对行尾

 

4、行间跳转

         #G = #gg:跳转至第#行;

         G:最后一行

         gg:第一行

         末行模式下,直接给出行号即可

        

四、翻屏

Ctrl+f: 向下翻一屏

Ctrl+b: 向上翻一屏

 

Ctrl+d: 向下翻半屏

Ctrl+u: 向上翻半屏

 

五、删除单个字符

x: 删除光标所在处的单个字符

#x: 删除光标所在处及向后的共#个字符

 

六、删除命令: d

d命令跟跳转命令组合使用;

#dw, #de, #db,#d$,#d0,#d^

#df@, #dt@

 

dd: 删除当前光标所在行

#dd: 删除包括当前光标所在行在内的#行;

 

末行模式下:

StartADD,EndADDd

         .: 表示当前行

         $: 最后一行

         +#: 向下的#行



e.g: 1,8d; 1,.d; 1,$d; 3,+23d; .,+3d, -3, $d, .,$-2d        



七、粘贴命令 p

p: 如果删除或复制为整行内容,则粘贴至光标所在行的下方,如果复制或删除的内容为非整行,则粘贴至光标所在字符的后面;

P: 如果删除或复制为整行内容,则粘贴至光标所在行的上方,如果复制或删除的内容为非整行,则粘贴至光标所在字符的前面;

 

八、复制命令 y

         用法同d命令

        

九、修改:先删除内容,再转换为输入模式

         c: 用法同d命令

 

十、替换:r

R: 替换模式

 

十一、撤消编辑操作 u

u:撤消前一次的编辑操作

         连续u命令可撤消此前的n次编辑操作,vi只保存了此前的50次操作

#u: 直接撤消最近#次编辑操作

 

撤消最近一次撤消操作:Ctrl+r

 

十二、重复前一次编辑操作

.

 

十三、可视化模式

v: 按字符选取

V:按行选取

ctrl+v:按矩形选取

 

十四、查找

/PATTERN:向下查找

?PATTERN:向上查找

         n:下一个查找结果

         N:上一个查找结果

 

十五、查找并替换

在末行模式下使用s命令,格式同sed一样

ADDR1,ADDR2 s@PATTERN@string@gi

1,$:全文范围

%:表示全文,等于 1,$

g:全局替换

i:忽略大小写

 

07_02_bash脚本编程之六使用脚本选项及组合条件测试(^ - 39



练习:

将/etc/yum.repos.d/server.repo文件中的ftp://instructor.example.com/pub替换为http://172.16.0.1/yum

 

%s/ftp:\/\/instructor\.example\.com\/pub/http:\/\/172.16.0.1\/yum/g

%s@ftp://instructor\.example\.com/pub@http://172.16.0.1/yum@g

 

文件内容如下:

# repos on instructor for classroom use

 

# Main rhel5 server

[base]

name=Instructor Server Repository

baseurl=ftp://172.16.0.1/pub/Server

gpgcheck=0

 

# This one is needed for xen packages

[VT]

name=Instructor VT Repository

baseurl=ftp://172.16.0.1/pub/VT

gpgcheck=0

 

# This one is needed for clustering packages

[Cluster]

name=Instructor Cluster Repository

baseurl=ftp://172.16.0.1/pub/Cluster

gpgcheck=0

 

# This one is needed for cluster storage (GFS, iSCSI target, etc...) packages

[ClusterStorage]

name=Instructor ClusterStorage Repository

baseurl=ftp://172.16.0.1/pub/ClusterStorage

gpgcheck=0

 

十六、使用vim编辑多个文件

vim FILE1 FILE2 FILE3

:next 切换至下一个文件

:prev 切换至前一个文件

:last 切换至最后一个文件

:first 切换至第一个文件

 

退出

:qa 全部退出

 

十七、分屏显示一个文件

Ctrl+w, s: 水平拆分窗口,或末行模式下sp(split)

Ctrl+w, v: 垂直拆分窗口,或末行模式下vs

 

在窗口间切换光标:

Ctrl+w, ARROW

 

:qa 关闭所有窗口

 

十八、分窗口编辑多个文件

vim -o FILE: 水平分割显示

vim -O FILE: 垂直分割显示

 

十九、将当前文件中部分内容另存为另外一个文件

末行模式下使用w命令

:w

:ADDR1,ADDR2 w /path/to/somewhere

 

二十、将另外一个文件的内容填充在当前文件中

:r /path/to/somefile

 

二十一、跟shell交互,执行shell命令

:! COMMAND

 

二十二、高级话题

1、显示或取消显示行号

:set number

:set nu

 

:set nonu

 

2、显示忽略或区分字符大小写

:set ignorecase

:set ic

 

:set noic

 

3、设定自动缩进

:set autoindent

:set ai

:set noai

 

4、查找到的文本高亮显示或取消    

:set hlsearch

:set nohlsearch

 

5、语法高亮

:syntax on

:syntax off

 

二十三、配置文件

/etc/vimrc:全局,所有用户生效

~/.vimrc:个别用户生效

 

vimtutor:vim练习

 

vim -r  FILE:恢复上次编辑的状态

第十一章、Linux文件查找详解



07_03_Linux文件查找详解



文本查找工具:grep, egrep, fgrep

 

文件查找:

1. locate:

         非实时,模糊匹配,查找是根据全系统文件数据库进行的;

# updatedb, 手动生成文件数据库

速度快

 

2. find

         实时

         精确

         支持众多查找标准

         遍历指定目录中的所有文件完成查找,速度慢;

        

find 查找路径 查找标准 查找到以后的处理动作

    查找路径:默认为当前目录

    查找标准:默认为指定路径下的所有文件

    处理运作:默认为显示

 

匹配标准:

         -name 'FILENAME':对文件名作精确匹配

                   文件名通配:

                            *:任意长度的任意字符

                            ?:任意单个字符

                            []:任意指定范围内的字符

         -iname 'FILENAME': 文件名匹配时不区分大小写

         -regex PATTERN:基于正则表达式进行文件名匹配

        

         -user USERNAME: 根据属主查找

         -group GROUPNAME: 根据属组查找

        

         -uid UID: 根据UID查找

         -gid GID: 根据GID查找(用户或组被删除后,属于这个用户或组的文件全部换成ID号)

        

         -nouser:查找没有属主的文件

         -nogroup: 查找没有属组的文件

        

         -type:文件类型

                   f:普通文件

                   d:目录

                   c:字符设备

                   b:块设备

                   l:符号链接

                   p:管道文件

                   s:套接字文件

        

         -size [+|-]:文件大小(默认单位为字节)

                   #k:KB

                   #M: MB

                   #G: GB



         -mtime:修改时间(天)

         -ctime:创建时间

         -atime:访问时间

                   [+|-]#

         -mmin:单位为分钟

         -cmin:

         -amin:

                   [+|-]#

                  

         -perm MODE:权限精确匹配

                   /MODE: 任意一位匹配即满足条件

                   -MODE: 文件权限能完全包含此MODE时才符合条件

                  

                   -644

                   644: rw-r--r--

                   755: rwxr-xr-x

                   750: rwxr-x---

         eg: find ./ -perm -001

         

 

组合条件:

         -a:与

         -o:或

         -not:非

 

组合条件练习:

1. 查找/tmp目录下,不是目录并且还不是套接字类型的文件

    find /tmp -not -type d -a -not -type s

2. 查找/tmp/test目录下,属主不是user1,也不是user2的文件;

    find /tmp/test -not -user user1 -a -not -user user2

    find /tmp/test -not \( -user user1 -o -user user2 \)

 

 

动作:

         -print: 显示

         -ls:类似ls -l的形式显示每一个文件的详细

         -ok COMMAND {} \; :每一次执行COMMAND前都需要用户确认

         -exec COMMAND {} \;:不需要确认



综合练习: 

1、查找/var目录下属主为root并且属组为mail的所有文件;

find /var -user root -group mail

 

2、查找/usr目录下不属于root,bin,或student的文件;

find /usr -not -user root -a -not -user bin -a -not -user student

find /usr -not \( -user root -o -user bin -o -user student \)

 

3、查找/etc目录下最近一周内内容修改过且不属于root及student用户的文件;

find /etc -mtime -7 -not \ ( -user root -o -user student \)

find /etc -mtime -7 -not -user root -a -not -user student

 

4、查找当前系统上没有属主或属组且最近1天内曾被访问过的文件,并将其属主属组均修改为root;

find / \( -nouser -o -nogroup \) -a -atime -1 -exec chown root:root {} \;

 

5、查找/etc目录下大于1M的文件,并将其文件名写入/tmp/etc.largefiles文件中;

find /etc -size +1M >> /tmp/etc.largefiles

 

6、查找/etc目录下所有用户都没有写权限的文件,显示出其详细信息;

find /etc -not -perm /222 -ls   



xargs命令

find /etc/ -size +1M -exec echo {} >> /tmp/etc.largefiles \;



上面的命令可以借助xargs,写成:

find /etc/ -size +1M | xargs echo >> /tmp/etc.largefiles

第十二章、特殊权限SUID等详解



07_04_特殊权限SUID等详解

 

特殊权限

e.g: 

ls -l /etc/passwd

passwd: s权限



三个特殊权限: 

1. SUID: 运行某程序时,相应进程的属主是程序文件自身的属主,而不是启动者;

         chmod u+s FILE

         chmod u-s FILE

                   如果FILE本身原来就有执行权限,则SUID显示为s;否则显示S;

2. SGID: 运行某程序时,相应进程的属组是程序文件自身的属组,而不是启动者所属的基本组;

         chmod g+s FILE

         chmod g-s FILE

                   目录SGID权限的特殊应用:在一个develop team,中的三个用户 hadoop, hbase, hive,如何做到三个用户都可以在

                   /tmp/project/下创建、删除编辑文件(包括别人创建的文件)。

                            develop

3. Sticky: 在一个公共目录,每个都可以创建文件,删除自己的文件,但不能删除别人的文件;

         chmod o+t DIR

         chmod o-t DIR

      

三个特殊位组合使用:  

000:

001:

...

110:

111:

 

chmod 5755 /backup/test, 第一位表示这三个特殊权限位

 

设置特殊权限位的umask

umask 0022

第十三章、facl及用户及Linux终端

 

08_01_facl及用户及Linux终端



文件系统访问列表:



如何让tom的文件被jerry读写?

用户名:tom, 基本组:tom 

1. 添加jerry访问tom文件的权限: other: rw-

但是这样其他用户也具有了访问权限,不安全。

 

2. 修改文件的属组为jerry,但是普通用户没有权限执行chown命令

3. FACL

 

FACLFilesystem Access Control List

利用文件扩展保存额外的访问控制权限,可以做到只把jerry的访问权限改为: rw-

 

1. setfacl

         -m: 设定额外的访问控制列表

                   u:UID:perm

                   g:GID:perm

         -x:取消

                   u:UID

                   g:GID

         -b Remove all



2. getfacl查看文件的访问控制列表

 


e.g: setfacl -m u:hadoop:rw inittab

       setfacl -x u:hadoop inittab



添加访问控制列表后

使用ls -l 查看文件,权限位最后多一个+

-rw-rwxr--+ 1 root  root   905 7月  16 09:19 inittab



权限验证顺序

一般情况:Owner ->Group -> Other

有facl后:Owner -> facl, user -> Group -> facl, group ->Other



终端有关的几个命令:

1. w:查看所用登录的用户及正在执行的命令

2. who: 查看所用登录的用户,三个字段:用户名,登录终端,时间,注释

    -r:显示当前运行级别



练习:

每隔5秒钟,就来查看hadoop是否已经登录,如登录,显示其已经登录,并退出;

sleep命令可以定时

 

3. whoami:查看有效用户

who am i : 查看真实用户



终端类型:

    console:控制台

    pty: 物理终端(VGA)

    tty:虚拟终端 (VGA)

    ttyS:串行终端

    pts/#:伪终端

 

4. last,显示/var/log/wtmp文件,显示用户登录历史及系统重启历史

         -n #: 显示最近#次的相关信息

lastb,/var/log/btmp文件,显示用户错误的登录尝试

         -n #:

lastlog: 显示每一个用户最近一次的成功登录信息;

         -u USERNAME: 显示特定用户最近的登录信息

 

5. basename:取得路径的基名

         $0: 执行脚本时的脚本路径及名称

dirname:去除基名,取得路径的路径

        

6. mail:邮件

e.g: cat /etc/inittab | mail -s "Subject" root

        mail -s "Subject" root < /etc/inittab

 

7. hostname: 显示主机名

hostname www.magedu.com 修改hostname

$HOSTNAME 保存的是登录设定的主机名,



练习:

如果当前主机的主机名不是www.magedu.com,就将其改为www.magedu.com

[ `hostname` != "www.magedu.com" ] && hostname www.magedu.com 



如果当前主机的主机名是localhost,就将其改为www.magedu.com

 

如果当前主机的主机名为空,或者为(none),或者为localhost,就将其改为www.magedu.com

[ -z `hostname` ] || [ `hostname` == '(none)' -o `hostname` == 'localhost' ] && hostname www.magedu.com

 

第十四章、磁盘及文件系统管理详解



08_03_磁盘及文件系统管理详解之一

 

磁盘管理:     

机械式硬盘:

         U盘、光盘、软盘、硬件、磁带  

此处查看PPT Linux入门.ppt (search: 文件系统)

补充磁盘分区、文件系统、inodeVFS等相关知识后继续。



分区以柱面为单位进行划分。

inode: index node, 保存了文件的信息,大小,属主,属组,时间等。

 



inode位图,块位图

 



1. ln [-s -v] SRC DEST

 

硬链接:

         1、只能对文件创建,不能应用于目录;

         2、不能跨文件系统;

         3、创建硬链接会增加文件被链接的次数;

        

符号链接:

         1、可应用于目录;

         2、可以跨文件系统;

         3、不会增加被链接文件的链接次数;

         4、其大小为指定的路径所包含的字符个数;

 

2. du: 显示路径下所有目录占用磁盘大小

         -s: 路径占用磁盘大小

         -h: human readable

        

3. df: 显示整个磁盘分区使用情况

        -i: 显示inode信息替代块信息

        -P: posix输出格式(文件名太长不换行)

 

       

08_04_磁盘及文件系统管理详解之二

 

设备文件:

         b: 按块为单位,随机访问的设备;如硬盘

         c:按字符为单位,线性设备;如键盘

        

 

ls -l /dev

         主设备号(major number)

                   标识设备类型

         次设备号(minor number)

                   标识同一种类型中不同设备



设备文件作为设备的访问入口。



tty 命令可以查看对应设备文件

[root@CentOS tmp]# tty

/dev/pts/2

echo "hello" >> /dev/pts/1

 

mknod

mknod [OPTION]... NAME TYPE [MAJOR MINOR]

         -m MODE

        

硬盘设备的设备文件名:

IDE, ATA:hd

SATA:sd

SCSI: sd

USB: sd

         a,b,c,...来区别同一种类型下的不同设备

        

IDE:

         第一个IDE口:主、从

                   /dev/hda, /dev/hdb

         第二个IDE口:主、从

                   /dev/hdc, /dev/hdd

 

sda, sdb, sdc, ...

 

hda分区:

         hda1: 第一个主分区

         hda2:

         hda3:

         hda4:

         hda5: 第一个逻辑分区

        

Linux支持的文件系统

    传统:ext2, ext3, ext4, reiserfs, xfs, jfs

    光盘:iso9660

    集群文件系统:GFS2, OCFS2

    网络文件系统: NFS, CIFS

 

低级格式化:将空白的磁盘划分出柱面和磁道,再将磁道划分为若干个扇区等

高级格式化:创建文件系统

        

VFSvirtual file system

一个分区就是一个独立的文件系统,可以单独格式化



查看当前系统识别了几块硬盘:

fdisk -l [/dev/to/some_device_file]

 

管理磁盘分区:

fdisk /device/path

         p: 显示当前硬件的分区,包括没保存的改动

         n: 创建新分区

                   e: 扩展分区

                   p: 主分区

                   l: 逻辑分区

         d: 删除一个分区

         w: 保存退出

         q: 不保存退出

         t: 修改分区类型

                   L:

         l: 显示所支持的所有类型

        

partprobe: 让内核重读分区表,cat /proc/partations 中查看分区表,  

    partprobe [/dev/sda/] 



partx Redhat6.0中类似partprobe的命令       

 

 

09_01_磁盘及文件系统管理详解之三 

 

查看Linux入门.ppt(search: 超级块),补充块组、超级块等相关知识。



 

 

 

超级块(Super Block)

        描述整个分区的文件系统信息,例如块大小、文件系统版本号、上次mount的时间等等

        超级块在每个块组的开头都有一份拷贝

 

块组描述符表(GDT,Group Descriptor Table)

        由很多块组描述符组成,整个分区分成多少个块组就对应有多少个块组描述符

        每个块组描述符(Group Descriptor)存储一个块组的描述信息,例如在这个块组中从哪里开始是inode表,从哪里开始是数据块,空闲的inode和数据块还有多少个等等

        和超级块类似,块组描述符表在每个块组的开头也都有一份拷贝,这些信息是非常重要的,一旦超级块意外损坏就会丢失整个分区的数据,一旦块组描述符意外损坏就会丢失整个块组的数据,因此它们都有多份拷贝

 

块位图(Block Bitmap)

        块位图就是用来描述整个块组中哪些块已用哪些块空闲的,它本身占一个块,其中的每个bit代表本块组中的一个块,这个bit为1表示该块已用,这个bit为0表示该块空闲可用

        与此相联系的另一个问题是:在格式化一个分区时究竟会划出多少个块组呢?主要的限制在于块位图本身必须只占一个块

 

inode位图(inode Bitmap)

        和块位图类似,本身占一个块,其中每个bit表示一个inode是否空闲可用

 

inode表(inode Table)

        一个文件除了数据需要存储之外,一些描述信息也需要存储,例如文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,也就是ls -l命令看到的那些信息,这些信息存在inode中而不是数据块中

        每个文件都有一个inode,一个块组中的所有inode组成了inode表

        inode表占多少个块在格式化时就要决定并写入块组描述符中

        mke2fs格式化工具的默认策略是一个块组有多少个8KB就分配多少个inode

 

数据块(Data Block)

        对于常规文件,文件的数据存储在数据块中

        对于目录,该目录下的所有文件名和目录名存储在数据块中,文件名保存在它所在目录的数据块中

            除文件名之外,ls -l命令看到的其它信息都保存在该文件的inode中

            目录也是一种文件,是一种特殊类型的文件

        对于符号链接,如果目标路径名较短则直接保存在inode中以便更快地查找,如果目标路径名较长则分配一个数据块来保存

        设备文件、FIFO和socket等特殊文件没有数据块,设备文件的主设备号和次设备号保存在inode中

 

 

inode table格式: 

 

 

 

ext3比ext2多一个日志区,存入元数据区的inode,先放入日志区,文件写完成后移动到元数据区

 

09_02_磁盘及文件系统管理详解之四

 

文件系统管理

格式化:重新创建文件系统会损坏原有文件

 

创建分区

1. fdisk /dev/sda

2. n -> e -> 4 -> ->  创建一个扩展分区,使用MBR第四个位置,从开头到结尾(使用所有剩余的空间)

3. n -> +5G  创建一个5G的逻辑分区

4. w  保存退出

5. partprobe /dev/sda 让内核识别新建分区,cat /proc/partitions 

 

mkfs: make file system,创建文件系统

         -t FSTYPE:指定文件系统类型



cat /proc/filesystems : 查看当前内核所支持文件系统类型

文件系统类型:

         ext2

         ext3:比ext2多一个journal区

         vfat: fat32

        

mkfs其实会调用其他的程序

mkfs -t ext2 = mkfs.ext2

mkfs -t ext3 = mkfs.ext3

 

专门管理ext系列文件系统:

1. mke2fs

         -j: 创建ext3类型文件系统

         -b BLOCK_SIZE: 指定块大小,默认为4096;可用取值为1024、2048或4096;

         -L LABEL:指定分区卷标;

         -m #: 指定预留给超级用户的块数百分比

         -i #: 用于指定为多少字节的空间创建一个inode,默认为8192;这里给出的数值应该为块大小的2^n倍;

         -N #: 指定inode个数;

         -F: 强制创建文件系统;

         -E: 用户指定额外文件系统属性;

 

2. blkid: 查询或查看磁盘设备的相关属性

         UUID:通用唯一识别码 (Universally Unique Identifier)

         TYPE:文件系统类型

         LABEL: 卷标

        

3. e2label: 用于查看或定义卷标

         e2label 设备文件卷标: 设定卷标

        

4. tune2fs: 调整文件系统的相关属性

         -j: 不损害原有数据,将ext2升级为ext3;

         -L LABEL: 设定或修改卷标;

         -m #: 调整预留百分比;

         -r #: 指定预留块数;

         -o: 设定默认挂载选项;

                   acl

         -c #:指定挂载次数达到#次之后进行自检,0或-1表关闭此功能;

         -i #: 每挂载使用多少天后进行自检;0或-1表示关闭此功能;

         -l: 显示超级块中的信息;

        

5. dumpe2fs: 显示文件属性信息

         -h: 只显示超级块中的信息

        

6. fsck: 检查并修复Linux文件系统

         -t FSTYPE: 指定文件系统类型

         -a: 自动修复

        

7. e2fsck: 专用于修复ext2/ext3文件系统

         -f: 强制检查;

         -p: 自动修复;

        

 

一个文件系统想要使用必须挂载到根文件系统

挂载:将新的文件系统关联至当前根文件系统

卸载:将某文件系统与当前根文件系统的关联关系预以移除;

 

8. mount:挂载

mount 设备 挂载点

         设备:

                   设备文件:/dev/sda5

                   卷标:LABEL=“”

                   UUID: UUID=“”

         挂载点:目录

                   要求:

                            1、此目录没有被其它进程使用;

                            2、目录得事先存在;

                            3、目录中的原有的文件将会暂时隐藏;

 

新挂载的文件系统下会出现

新建的文件系统: lost+found 目录



mount: 显示当前系统已经挂载的设备及挂载点

mount [options] [-o options] DEVICE MOUNT_POINT

         -a: 表示挂载/etc/fstab文件中定义的所有文件系统

         -n: 默认情况下,mount命令每挂载一个设备,都会把挂载的设备信息保存至/etc/mtab文件;使用-n选项意味着挂载设备时,不把信息写入此文件;

         -t FSTYPE: 指定正在挂载设备上的文件系统的类型;不使用此选项时,mount会调用blkid命令获取对应文件系统的类型;

         -r: 只读挂载,挂载光盘时常用此选项

         -w: 读写挂载

         -o: 指定额外的挂载选项,也即指定文件系统启用的属性;

                   remount: 重新挂载当前文件系统

                   ro: 挂载为只读

                   rw: 读写挂载

e.g: mount -o remount,ro /dev/sda5

挂载完成后,要通过挂载点访问对应文件系统上的文件;

 

9. umount: 卸载某文件系统

         umount 设备

         umount 挂载点                

            -l: 强制卸载

 

         卸载注意事项:

                   挂载的设备没有进程使用;

 

 

 

练习:

1、创建一个2G的分区,文件系统为ext2,卷标为DATA,块大小为1024,预留管理空间为磁盘分区的8%;挂载至/backup目录,要求使用卷标进行挂载,且在挂载时启动此文件系统上的acl功能;

# mke2fs -L DATA -b 1024 -m 8  /dev/sda7

 

# mount -o acl LABEL=DATA /backup

或分两步:

# tune2fs -o acl /dev/sda7

# mount LABEL=DATA /backup

 

2、将此文件系统的超级块中的信息中包含了block和inode的行保存至/tmp/partition.txt中;

# tune2fs -l | egrep -i  "block|inode" >> /tmp/partition.txt 

# dumpe2fs -h | egrep -i  "block|inode" >> /tmp/partition.txt 



3、复制/etc目录中的所有文件至此文件系统;而后调整此文件系统类型为ext3,要求不能损坏已经复制而来的文件;

# cp -r /etc/*  /backup

# tune2fs    -j /dev/sda7



4、调整其预留百分比为3%;

# tune2fs -m 3 -L DATA /dev/sda7



5、以重新挂载的方式挂载此文件系统为不更新访问时间戳,并验正其效果;

# stat /backup/inittab

# cat /backup/inittab

# stat

 

# mount -o remount,noatime /backup

# cat

# stat

 

6、对此文件系统强行做一次检测;

e2fsck -f /dev/sda7



7、删除复制而来的所有文件,并将此文件系统重新挂载为同步(sync);而后再次复制/etc目录中的所有文件至此挂载点,体验其性能变化;

# rm -rf /backup/*

# mount -o remount,sync /backup

# cp -r /etc/* /backup

 

 

09_03_磁盘及文件系统管理详解之五

 

swap分区: 类似windows的虚拟内存

page out = swap in

page in = swap out



free: 查看当前系统上物理内存和交换分区的使用情况 

         -m: MB为单位显示

# free -m
             total       used       free     shared    buffers     cached
Mem:           490        394         95          0        142        101
-/+ buffers/cache:        149        340
Swap:         1023          0       1023


-/+ buffers/cache:        149(减去buffers+cached)         340(加上buffers+cached)


buffer: 存放元数据

cache: 存放数据

 

创建交换分区: mkswap, swapon

 

1. fdisk /dev/sda

2. n -> -> +1G 创建一个新分区,大小1G

3. t -> 8 -> L -> 82    调整分区类型为82(Linux swap),L查看可用分区类型

4. w

5. mkswap /dev/sda8  创建交换分区文件系统

         -L LABEL

 

6. swapon /dev/sda8  启用交换分区

         -a:启用所有的定义在/etc/fstab文件中的交换设备

    swapoff /dev/sda8 关闭交换分区

 

 

回环设备:使用软件来模拟实现硬件

 

 

loopback, 使用软件来模拟实现硬件

如果磁盘已经没有空间可以创建新的分区,可以创建一个镜像文件,当作一块硬盘来用。

 

dd命令:

         if=数据来源

         of=数据存储目标

         bs=# :block size,以多大为单位,如1M

         count=#:计数

         seek=#: 创建数据文件时,跳过的空间大小;   

            dd if=/dev/zero of=/root/tmp seek=1023 bs=1M count=1

            表示跳过1023个bs,复制1个bs,ls查看文件大小为1G,du -sh 查看文件实际只有1M

 

dd不以文件为单位,而直接复制文件流,可以实现只复制一部分文件。

 

e.g: 

dd if=/dev/sda of=/mnt/usb/mbr.backup bs=512 count=1  备份磁盘MBR

dd if=/mnt/usb/mbr.backup of=/dev/sda bs=512 count=1  恢复MBR

 

使用文件创建swap分区:

1. dd if=/dev/zero of=/var/swapfile bs=1M count=1024  创建一个1G的文件

2. mkswap /var/swapfile

3. swapon /var/swapfile

 

cat /dev/cdrom > /root/rhel5.iso 把光盘制作成ISO镜像



/dev/null :数据黑洞,吞噬一切数据

/dev/zero:数据泡泡,产生无限0

        

mount命令,可以挂载iso镜像;

mount DEVICE MOUNT_POINT

         -o loop: 挂载本地回环设备

 

文件系统的配置文件/etc/fstab

         OS在初始时,会自动挂载此文件中定义的每个文件系统



如果只是使用命令:mount /dev/sda5 /mnt/test,重启后挂载的文件就不存在了

    

/etc/fstab 格式:    

要挂载的设备         挂载点              文件系统类型                   挂载选项                   转储频率(每多少天做一次完全备份)           文件系统检测次序(只有根可以为1)                

/dev/sda5                  /mnt/test                   ext3          defaults             0 0

 

mount -a:挂载/etc/fstab文件中定义的所有文件系统

 

 

fuser: 查看正在使用文件或套接字文件的进程

         -v: 查看某文件上正在运行的进程

         -k: kill 

         -m: mount

        

         fuser -km MOUNT_POINT:终止正在访问此挂载点的所有进程

        

练习:

1、创建一个5G的分区,文件系统为ext3,卷标为MYDATA,块大小为1024,预留管理空间为磁盘分区的3%,要求开机后可以自动挂载至/data目录,并且自动挂载的设备要使用卷标进行引用;

# fdisk /dev/sdb

   n -> p -> -> +5G -> w

# mke2fs -j -L MYDATA -b 1024 -m 3

# mkdir /data

# vi /etc/fstab加一行

LABEL='MYDATA'        /data        ext3        default         0 0



2、创建一个本地回环文件/var/swaptemp/swapfile来用于swap,要求大小为512MB,卷标为SWAP-FILE,且开机自动启用此交换设备;

# mkdir /var/swaptemp

# dd if=/dev/zero of=/var/swaptemp/swapfile bs=1M count=512

# mkswap -L SWAP-FILE /var/swaptemp/swapfile

# vi /etc/fstab

/var/swaptemp/swapfile       swap                  swap                  defaults             0 0



3、上述第一问,如何让其自动挂载的同时启用ACL功能;

#vi /etc/fstab

LABEL='MYDATA'              /data                  ext3          defaults,acl      0 0

 

第十五章、Linux压缩及归档



 

1. 压缩、解压缩命令



压缩格式:gz, bz2, xz, zip, Z

压缩算法:算法不同,压缩比也会不同;

 

uncompress

 

比较流行的压缩工具:

 

         gzip /PATH/TO/SOMEFILE:压缩完成后会删除原文件

                   -d:解压缩

                   -#:1-9,指定压缩比,默认是6;

gunzip:

         gunzip /PATH/TO/SOMEFILE.gz: 解压完成后会删除原文件

zcat:

        zcat /PATH/TO/SOMEFILE.gz:不解压的情况,查看文本文件的内容

        

比gzip有着更大压缩比的压缩工具,使用格式近似

         bzip2 /PATH/TO/SOMEFILE

                   -d: 解压缩

                   -#: 1-9,默认是6

                   -k: 压缩时保留原文件

                  

         bunzip2 /PATH/TO/SOMEFILE.bz2: 解压

         bzcat: 查看,同zcat

 

         xz /PATH/TO/SOMEFILE

                   -d: 解压缩

                   -#: 1-9, 默认是6

                   -k: 压缩时保留原文件

         unxz:解压

         xzdec: 解压,内容输出到屏幕上

         xzcat:查看

 

4). zip: 既归档又压缩的工具

         zip FILENAME.zip FILE1 FILE2 ...: 压缩后不删除原文件

         unzip FILENAME.zip

        



2. archive: 归档,多个文件整合为一个文件,归档本身并不意味着压缩

 

1). tar: 归档工具, .tar

         -c: 创建归档文件

         -f FILE.tar: 操作的归档文件

         -x: 展开归档

         --xattrs: 归档时,保留文件的扩展属性信息

         -t: 不展开归档,直接查看归档了哪些文件

 

         -zcf: 归档并调用gzip压缩

         -zxf: 调用gzip解压缩并展开归档,-z选项可省略

        

         -jcf: bzip2

         -jxf:

        

         -Jcf: xz

         -Jxf:

 

2). cpio: 归档工具

        -i,--extract: 从归档文件中提取出文件

        -o: 创建归档文件

        -d: 创建需要的路径

        -H: 使用指定的归档格式

        --quiet: 静默模式,Do not print the number of blocks copied

        /boot/initrd-*.img 文件使用gzip 解压后得到的img文件是cpio归档文件

 

        

练习:写一个脚本

从键盘让用户输入几个文件,脚本能够将此几个文件归档压缩成一个文件;

read:

        -p "PROMPT": 给出提示

        -t: 超时时间

 

#read num age

输入:123 34

num = 123

age = 34

第十六章、Raid及mdadm命令



 

10_01_Raid及mdadm命令之一 (17 - $)



 

IDE: 133Mbps

SATA: 300Mbps, 600Mbps, 6Gbps

USB 3.0:  480Mbps

SCSI: Small Computer Syetem Interface,UltraSCSI, 320Mbps, 并行

SAS: 串行SCSI

 

 

 

0:条带

         性能提升: 读,写

         冗余能力(容错能力): 无

         空间利用率:nS

         至少2块盘

1:镜像

         性能表现:写性能下降,读性能提升

         冗余能力:有

         空间利用率:1/2

         至少2块盘

2

3

4: 

5: 校验码

         性能表现:读,写提升

         冗余能力:有

         空间利用率:(n-1)/n

         至少需要3块

10: 先镜像,再条带

         性能表现:读、写提升

         冗余能力:有

         空间利用率:1/2

         至少需要4块

01:

         性能表现:读、写提升

         冗余能力:有

         空间利用率:1/2

         至少需要4块

50:

         性能表现:读、写提升

         冗余能力:有

         空间利用率:(n-2)/n

         至少需要6块

jbod:

         性能表现:无提升

         冗余能力:无

         空间利用率:100%

         至少需要2块

 

 

 

逻辑RIAD软件模拟

/dev/md0

/dev/md1



 



模式化的命令:

         创建模式

                   -C

                            专用选项:

                                     -l: 级别

                                     -n #: 设备个数

                                     -a {yes|no}: 是否自动为其创建设备文件

                                     -c: CHUNK大小, 2^n,默认为64K

                                     -x #: 指定空闲盘个数

         管理模式

                   --add, --remove, --fail | -f

                   mdadm /dev/md# --fail /dev/sda7

         监控模式

                   -F

         增长模式

                   -G

         装配模式

                   -A

 

 

mdadm -D /dev/md#

         --detail

        

         mdadm -S /dev/md#

                   --stop

 

创建一个空间大小为10G的RAID5设备;其chuck大小为32k;要求此设备开机时可以自动挂载至/backup目录;

 

         2G: 4个 512MB或2个1G的分区

mdadm -C /dev/md0 -l 0 -a yes -n 2 /dev/sdb{7,8}

cat /proc/mdstat



         2G:2个2G

        mdadm -C /dev/md1 -l 1 -a yes -n 2 /dev/sdb{7,8}      

 

                  

         -n #:指定周期长度,单位为秒,默认为2

格式: watch -n # 'COMMAND'

        

mdamd -D --scan > /etc/mdadm.conf

 

练习:

制作一个2G大小的RAID5

         2G: 3块1G的分区

第十七章、LVM

 

 

LVMLogical Volume Manager(逻辑卷管理)

LVM的概念和LVM存在的作用  

 

MD: meta device,multidisk

DM: Device Mapper

         逻辑设备

                   RAID, LVM2

 

MD: RAID

         snapshot: 快照,

         multipath: 多路径

 

PV:physical volume

VG:volume group

LV:logical volume

 

pv :

pvcreate, pvremove, pvscan, pvdisplay, pvmove



vg :

vgcreate, vgremove, vgextend, vgreduce, vgs, vgdisplay, vgscan



lv :

lvcreate, lvremove, lvextend, lvreduce, lvs, lvdisplay



 

 

         -s #: PE大小,默认为4MB

 

vgreduce

vgextend

        

 

lvremove



创建一个由两个物理卷组成的大小为20G的卷组myvg,要求其PE大小为16M;而后在此卷组中创建一个大小为5G的逻辑卷lv1,此逻辑卷要能在开机后自动挂载至/users目录,且支持ACL功能;

 





 

一、扩展逻辑卷;

lvextend:扩展物理边界

         -L [+]# /PATH/TO/LV

  

resize2fs:扩展逻辑边界

         resize2fs -p /PATH/TO/LV

 

 

二、缩减逻辑卷;

注意:1、不能在线缩减,得先卸载;

           2、确保缩减后的空间大小依然能存储原有的所有数据;

           3、在缩减之前应该先强行检查文件,以确保文件系统处于一至性状态;

步骤:

0. df -lh,确保缩减后的空间大小依然能存储原有的所有数据

1. umount

2. e2fsck -f

                  

3. resize2fs:缩减逻辑边界

         resize2fs /PATH/TO/PV 3G

 

4. lvreduce:缩减物理边界

         lvreduce -L [-]# /PATH/TO/LV

 

5. 重新挂载

 

 

三、快照卷

1、生命周期为整个数据时长;在这段时长内,数据的增长量不能超出快照卷大小;

2、快照卷应该是只读的;

3、跟原卷在同一卷组内;

 

 

lvcreate

         -s:快照卷

         -p r|w

        

e.g: 

lvcreate -L # -n SLV_NAME -p r /PATH/TO/LV 

第十八章、Linux网络配置



 

network.ppt: CSMA/CD

自己学习补充网络相关知识,想要详细了解的推荐一本书《计算机网络第五版》- 作者谢希仁。

 

11_02_Linux网络配置之二 IP报文



IP报文头:

 



 



IPv4点分十进制:

0000 0000 - 1111 1111

0-255

 

221.34.23.12

网络地址:

主机地址:

 

 

32位二进制

 

 

A类: 255.0.0.0, 8:

         0 000 0001 - 0 111 1111

         127个A类,127用于回环,1-126

         2^7-1个A类

         容纳多少个主机:2^24-2

         主机位全0:网络地址

         主机位全1:广播地址

B类:255.255.0.0, 16

         10 00 0000- 10 11 1111

         128-191

         129.1.0.0.

         130.1.0.0

         64个B类,2^14个B类网

         容纳多少个主机:2^16-2

C类:255.255.255.0, 24

         110 0 0000 - 110 1 1111

         192-223

         32个C类, 2^21个C类网

         容纳多个少个主机:2^8-2

 

私有地址:

         A类:10.0.0.0/8

         B类:172.16.0.0/16-172.31.0.0/16

         C类:192.168.0.0/24-192.168.255.0/24

        

路由:选路

        

        

ICANN, IANA

        

D类:

         1110 0000 - 1110 1111

         224-239

E类:

 

TCP报文头:

 

 







主机接入网络需要配置:

 

IP

NETMASK

GATEWAY

HOSTNAME

DNS1

DNS2

DNS3



完成以上配置的方式:

         1. 手动指定

         2. DHCP:Dynamic Host Configuration Protocol

                   169.254.

 

路由

 

Linux: 网络属于内核的功能

IP地址属于内核,不属于网卡

 

 

定义网卡名:

lo:本地回环

以太网网卡:ethX

点对点:pppX

RHEL5: /etc/modprobe.conf, 使用alias定义网卡名

RHEL6: /etc/udev/rules.d/70-persistent-net.rules

 

         -a: 显示所有接口的配置信息

        

ifconfig ethX IP/MASK [up|down]

         配置的地址立即生效,但重启网络服务或主机,都会失效;

        

网络服务脚本:

RHEL5:  /etc/init.d/network {start|stop|restart|status}

RHEL6: /etc/init.d/NetworkManager {start|stop|restart|status}

 

         add: 添加

                   -host: 主机路由

                   -net:网络路由

                            -net 0.0.0.0

        

        route add -net|-host DEST gw NEXTHOP

        route add default gw NEXTHOP

        e.g:   route add -net 10.0.0.0/8 gw 192.168.10.1

 

        del:删除

                 -host

                 -net

        e.g:

        route del -net 10.0.0.0/8

        route del -net 0.0.0.0

        route del default

 

        route 命令所做出的改动在重启网络服务或主机后失效;

 

        查看:

             route -n: 以数字方式显示各主机或端口等相关信息

        

 

网络配置文件: 网络服务总开关,包括主机名

/etc/sysconfig/network 

 

网络接口配置文件:每个接口有一个对应的文件

/etc/sysconfig/network-scripts/ifcfg-INTERFACE_NAME

DEVICE=: 关联的设备名称,要与文件名的后半部“INTERFACE_NAME”保持一致;

BOOTPROTO={static|none|dhcp|bootp}: 引导协议;要使用静态地址,使用static或none;dhcp表示使用DHCP服务器获取地址;

IPADDR=: IP地址

NETMASK=:子网掩码

GATEWAY=:设定默认网关;

ONBOOT=:开机时是否自动激活此网络接口;

HWADDR=:硬件地址,要与硬件中的地址保持一致;可省;

USERCTL={yes|no}: 是否允许普通用户控制此接口(启用或禁用);

PEERDNS={yes|no}: 是否在BOOTPROTO为dhcp时接受由DHCP服务器指定的DNS地址;

 

修改配置文件不会立即生效,但重启网络服务或主机都会生效;

 

路由配置文件:

/etc/sysconfig/network-scripts/route-ethX

添加格式一:

DEST         via   NEXTHOP

 

添加格式二:

ADDRESS0=

NETMASK0=

GATEWAY0=

 

 

DNS服务器指定方法只有一种:

/etc/resolv.conf

nameserver DNS_IP_1

nameserver DNS_IP_2

 

指定本地解析:不通过DNS服务器解析

/etc/hosts

主机IP     主机名     主机别名

172.16.0.1                 www.magedu.com           www

 

域名解析顺序

/etc/hosts-->DNS服务

 

配置主机名:

hostname HOSTNAME - 立即生效,但不是永久有效;

配置文件:

/etc/sysconfig/network

HOSTNAME=

 

RHEL5使用gui修改网络配置文件:

         setup: system-config-network-tui

         system-config-network-gui

 

        

ifconfig 太过老旧,另一个强大的软件包:iproute2

 

 



         ip

                   link: 网络接口属性

                   addr: 协议地址

                   route: 路由

    

                 link

                           show

                                    ip -s link show; 显示统计信息

                           set

                                    ip link set DEV {up|down}

                           

                 addr

                           add

                                    label:指定别名

                                    ip addr add ADDRESS dev DEV

                           del

                                    ip addr del ADDRESS dev DEV

                           show

                                    ip addr show dev DEV to PREFIX

                           flush

                                    ip addr flush dev DEV to PREFIX

                route

                        add

                        change

                        replace

 

e.g:

ip link show

ip link set eth1 down; 禁用eth1

ip addr 

                  

一块网卡可以使用多个地址:

网络设备可以别名:

ethX:X

         eth0别名: eth0:0, eth0:1, ...

        

配置方法:

         1. ifconfig ethX:X IP/NETMASK

        

         2. vi /etc/sysconfig/network-scripts/ifcfg-ethX:X

         DEVICE=ethX:X

 

         非主要地址不能使用DHCP动态获取;

 

         eth1, 添加个地址192.168.100.1



e.g:   

ip addr add 192.168.100.1/24 dev eth1 label eth1:0

ip addr del 10.2.2.2/8 dev eth1

 

 

primary address:主地址

secondary adress:辅助地址

 

192.168.100.6

 

10.0.1.0/24, 192.168.100.6

 

ip命令配置路由:

route add -net 10.0.1.0/24 gw 192.168.100.6

 

ip route add to 10.0.1.0/24 dev eth1 via 192.168.100.6

         add, change, show, flush, replace

 

第十九章、Linux软件管理


 

程序组成部分:

         二进制程序

         库

         配置文件

         帮助文件

 

跟目录结构

/boot

/etc

/usr

/var

/dev

/lib

/tmp

/bin

/sbin

/proc

/sys

/mnt

/media

/home

/root

/misc

/opt

/srv

 

 

目录讲解:



/usr/share/man:帮助手册

 

         系统启动就需要用到的程序,这些目录不能挂载额外的分区,必须在根文件系统的分区上

            

         bin

         sbin

         lib

            

         bin

         sbin

         lib

         etc

         man

 

 

         这两个目录不能单独分区,默认为空;

        

辅助目录:

/dev: 设备,不能单独分区;

         2.6 内核后添加了:udev,动态加载设备文件

        

/root: 不能单独分区

 

/var:建议单独分区

     存放pid, lock, log文件



/boot:内核,initrd(initramfs)

         内核: bootloader负责加载,bootloader加载内核时并没有文件系统,bootloader能够识别文件系统结构

        应该单独分区,根文件系统所在分区可能使用LVM,而LVM是内核的功能。

 

 

系统启动次序:

POST-->BIOS(HD)-->(MBR)bootloader(文件系统结构,ext2, ext3, xfs)-->内核-->根

 

程序:指令+数据

         指令:芯片固化

                   CPU: 普通指令,特权指令

                   指令集

                  

 

软件包管理器的核心功能:

1、制作软件包;

2、安装、卸载、升级、查询、校验;

 

Linux三大发行版:Redhat, SUSE, Debian 使用的软件包管理工具

 

Redhat, SUSE: RPM

         Redhat Package Manager

         PRM is Package Manager



Debian: dpt

 

 

前端工具:yum, apt-get,为了解决依赖关系

后端工具:RPM, dpt

 

yum: Yellowdog Update Modifier

 

 



rpm命令:

         rpm:

                   数据库: /var/lib/rpm, 一旦损坏,rpm工具就会失效

         rpmbuild:

 

软件管理的工作包括:

安装、查询、卸载、升级、校验、数据库的重建、验正数据包等工作;

 

rpm命名:

包:组成部分

         主包:

                   bind-9.7.1-1.el5.i586.rpm

         子包:

                   bind-libs-9.7.1-1.el5.i586.rpm

                   bind-utils-9.7.1-1.el5.i586.rpm

包名格式:

         name-version-release.arch.rpm

         bind-major.minor.release-release.arch.rpm

 

major: 主版本号:重大改进

minor: 次版本号:某个子功能发生重大变化

release: 发行号:修正了部分bug,调整了一点功能

第二个release:rpm包的发行号



源码命名:bind-9.7.1.tar.gz     

 

rpm包格式分为:

         二进制格式:

                   rpm包作者下载源程序,编译配置完成后,制作成rpm包

                   bind-9.7.1-1.noarch.rpm

                   bind-9.7.1-1.ppc.rpm



         源码格式:需要自己编译,可以发挥硬件最大性能。

 

 

1、安装

rpm -i /PATH/TO/PACKAGE_FILE

         -h: 以#显示进度;每个#表示2%;

         -v: 显示详细过程

         -vv: 更详细的过程

         --nodeps: 忽略依赖关系;

         --replacepkgs: 重新安装,替换原有安装;

         --force: 强行安装,可以实现重装或降级;

        

一般使用:rpm -ivh /PATH/TO/PACKAGE_FILE

      

2、查询

rpm -q PACKAGE_NAME:查询指定的包是否已经安装

rpm -qa : 查询已经安装的所有包

 

rpm -qi PACKAGE_NAME: 查询指定包的说明信息;

rpm -ql PACKAGE_NAME: 查询指定包安装后生成的文件列表;

rpm -qc PACEAGE_NEME:查询指定包安装的配置文件;

rpm -qd PACKAGE_NAME: 查询指定包安装的帮助文件;

 

rpm -q --scripts PACKAGE_NAME: 查询指定包中包含的脚本

        

rpm -qf /path/to/somefile: 查询指定的文件是由哪个rpm包安装生成的;

        

如果某rpm包尚未安装,我们需查询其说明信息、安装以后会生成的文件;

rpm -qpi /PATH/TO/PACKAGE_FILE

rpm -qpl /PATH/TO/PACKAGE_FILE

 

3、升级

rpm -Uvh /PATH/TO/NEW_PACKAGE_FILE: 如果装有老版本的,则升级;否则,安装;

rpm -Fvh /PATH/TO/NEW_PACKAGE_FILE:如果装有老版本的,则升级;否则,退出;

         --oldpackage: 降级

        

4、卸载

rpm -e PACKAGE_NAME

         --nodeps

        

5、校验

rpm -V PACKAGE_NAME

        

6、重建数据库

rpm

          --rebuilddb: 重建数据库,一定会重新建立;

          --initdb:初始化数据库,没有才建立,有就不用建立;

 

7、检验来源合法性,及软件包完整性;

加密类型:

         1. 对称:加密解密使用同一个密钥

         2. 非对称:一对儿密钥,公钥,私钥;公钥隐含于私钥中,可以提取出来,并公开出去;       

         3. 单向:hash

 

# ls /etc/pki/rpm-gpg/

         RPM-GPG-KEY-redhat-release : 红帽公司的公钥

        

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release: 导入密钥文件



rpm -K /PAPT/TO/PACKAGE_FILE

         dsa, gpg: 验正来源合法性,也即验正签名;可以使用--nosignature,略过此项

         sha1, md5: 验正软件包完整性;可以使用--nodigest,略过此项

        



 

yum仓库中的元数据文件:

1. primary.xml.gz

         所有RPM包的列表;

         依赖关系;

         每个RPM安装生成的文件列表;



2. filelists.xml.gz

         当前仓库中所有RPM包的所有文件列表;



3. other.xml.gz

         额外信息,RPM包的修改日志;

 

4. repomd.xml

         记录的是上面三个文件的时间戳和校验和;

        

5. comps*.xml

        RPM包分组信息;

 

如何为yum定义repo文件

自己的yum配置文件保存在/etc/yum.respos.d下

 

[Repo_ID]

name=Description

baseurl=

         ftp://

         http://

         file:///

enabled={1|0}

gpgcheck={1|0}

gpgkey=

 

 

 

options:

-y: 自动回答为yes

--nogpgcheck

 

command:

list: 列表

         支持glob

         all

         available:可用的,仓库中有但尚未安装的

         installed: 已经安装的

         updates: 可用的升级

 

clean: 清理缓存

         [ packages | headers | metadata | dbcache | all ]

        

repolist: 显示repo列表及其简要信息

         all

         enabled:默认

         disabled

 

install: 安装

         yum install PACKAGE_NAME



localinstall: 安装本地rpm包,可以自动安装依赖包



update: 升级

update_to: 升级为指定版本

 

remove|erase:卸载

 

info: infomation,类似 rpm -qi

 

provides| whatprovides: 查看指定的文件或特性是由哪个包安装生成的;

 

包组管理:

groupinfo

grouplist

groupinstall

groupremove

groupupdate

 

 

使用光盘作为yum源:

/media/cdrom/{Server,VT,Cluster,ClusterStorage}

baseurl=file:///media/cdrom/Server

 

如何创建yum仓库:

createrepo

创建 repodata路径,生成源的元数据文件。

 

练习:

1、将系统安装光盘挂载至/media/yum目录,用其实现yum仓库;

2、配置使用http://172.16.0.1/yum/{Server,VT,Cluster,ClusterStorage}为可用yum仓库;

 

 

写一个脚本,完成如下功能:

说明:此脚本能够为指定网卡创建别名,则指定地址;使用格式如:mkethalias.sh -v|--verbose -i ethX

1、-i选项用于指定网卡;指定完成后,要判断其是否存在,如果不存在,就退出;

2、如果用户指定的网卡存在,则让用户为其指定一个别名,此别名可以为空;如果不空,请确保其事先不存在,否则,要报错,并让用户重新输入;

3、在用户输入了一个正确的别名后,请用户输入地址和掩码;并将其配置在指定的别名上;

4、如果用户使用了-v选项,则在配置完成后,显示其配置结果信息;否则,将不显示;

 

 

 

RPM安装:

         二进制格式:

         源程序-->编译-->二进制格式

                   有些特性是编译选定的,如果编译未选定此特性,将无法使用;

                   rpm包的版本会落后于源码包,甚至落后很多;bind-9.8.7, bind-9.7.2

                  

定制:手动编译安装

 

编译环境,开发环境

开发库,开发工具

 

Linux: C,

GNU: C

 

C,C++:

    gcc: GNU C Complier, C

    g++:

 

make: 项目管理工具,

         makefile: 定义了make(gcc,g++)按何种次序去编译这些源程序文件中的源程序

 

automake, --> makefile.in --> makefile

autoconf, --> configure

 

编译安装的三步骤:



前提:准备开发环境(编译环境)

安装"Development Tools"和"Development Libraries"

 

# tar

# cd

1. # ./configure 

         --help

         --prefix=/path/to/somewhere

         --sysconfdir=/PATH/TO/CONFFILE_PATH

         功能:1、让用户选定编译特性;2、检查编译环境;

2. # make

3. # make install

 

e.g: 编译安装tengine

# tar xf tengine-1.4.2.tar.gz

# cd tegnine-1.4.2

# ./configure --prefix=/usr/local/tengine --conf-path=/etc/tengine/tengine.conf

# make

# make install

# /usr/local/tengine/sbin/nginx

 

如果软件安装到了非默认路径下,需要做的修改:

1、修改PATH环境变量,以能够识别此程序的二进制文件路径;

         修改/etc/profile文件

         在/etc/profile.d/目录建立一个以.sh为名称后缀的文件,在里面定义export PATH=$PATH:/path/to/somewhere

2、默认情况下,系统搜索库文件的路径/lib, /usr/lib; 要增添额外搜寻路径:

         在/etc/ld.so.conf.d/中创建以.conf为后缀名的文件,而后把要增添的路径直接写至此文件中;

         # ldconfig 通知系统重新搜寻库文件

                   -v: 显示重新搜寻库的过程

3、头文件:输出给系统

         默认:/usr/include

         增添头文件搜寻路径,使用链接进行:

                   /usr/local/tengine/include/   /usr/include/

                   两种方式:

                   ln -s /usr/local/tengine/include/* /usr/include/ 或

                   ln -s /usr/local/tengine/include  /usr/include/tengine

4、man文件路径:安装在--prefix指定的目录下的man目录;/usr/share/man   

                   1、man -M /PATH/TO/MAN_DIR COMMAND

                   2、在/etc/man.config中添加一条MANPATH

                  

netstat命令:

         -r: 显示路由表

         -n: 以数字方式显示

        

         -t: 建立的tcp连接

         -u: 显示udp连接

         -l: 显示监听状态的连接

         -p: 显示监听指定的套接字的进程的进程号及进程名


二十章、Linux进程管理





学习进程及作业管理
ppt :  network.ppt



VSZ: +共享库

RSS: resident size

 

Uninterruptible sleep: 不可中断的睡眠

Interruptible sleep:可中断睡眠

 



 

进制优先级(0-139)

0-99:内核调整的

100-139:用户可控制

 

2.6内核选择一个进程的时间复杂度是O(1)



O:算法的时间复杂度

         O(1)

         O(n)

         O(logn)

         O(n^2)

         O(2^n)

 

         SysV风格(Sys5):-

         BSD风格:

 

ps - BSD风格

         a: 所有与终端有关的进程

         u: display user-oriented format

         x: 所有与终端无关的进程

        

进程的分类:

         跟终端相关的进程

         跟终端无关的进程

 

进程状态:

         D:不可中断的睡眠

         R:运行或就绪

         S:可中断的睡眠

         T:停止

         Z:僵死

        

         <:高优先级进程

         N:低优先级进程

         +:前台进程组中的进程

         l: 多线程进程

         s: 会话进程首进程

 

加中括号的进程是内核进程。

 

    -e: all

    -F: full format

    -l: long format

    -o: 指定显示字段



常用

         -elF

         -ef

         -eF

 

ps -o PROPERTY1,PROPERTY2

ps -o pid,comm,ni

 

          

pstree:显示当前系统上的进程树

 

pgrep: pgrep bash; pgrep -u root bash



pidof:根据程序名称,查找其相关进程的ID号;





topdisplay Linux tasks

 

S字段: 

<:高优先级的进程

N:低优先级的进程

l: 多线程进程

+:前台进程组中的进程

s: 会话进程的领导者

 

top子命令:

         M: 根据驻留内存大小进行排序

         P:根据CPU使用百分比进行排序

         T: 根据累计时间进行排序

        

         l: 是否显示平均负载和启动时间

         t: 是否显示进程和CPU状态相关信息

         m: 是否显示内存相关信息

        

         c: 是否显示完整的命令行信息

         q: 退出top

         k: 终止某个进程

 

top选项:

         -d: 指定延迟时长,单位是秒

         -b: 批模式

         -n #:在批模式下,共显示多少批

 

 

进程间通信(IPC: Inter Process Communication

         共享内存

         信号: Signal

         Semaphore

 

 

信号:

    查看信号:kill -l

 

重要的信号:

1: SIGHUP: 让一个进程不用重启,就可以重读其配置文件,并让新的配置信息生效;

2: SIGINT:Ctrl+c: 中断一个进程

9: SIGKILL:杀死一个进程

15: SIGTERM:终止一个进程, kill的默认信号

        

指定一个信号:

         1. 信号号码:kill -1

         2. 信号名称:kill -SIGKILL

         3. 信号名称简写:kill -KILL

 

结束进程:

kill PID

killall COMMAND

 



调整nice值:

调整已经启动的进程的nice值:

renice NI PID

 

在启动时指定nice值:

nice -n NI COMMAND

 

前后台作业

前台作业:占据了命令提示符

后台作业:启动之后,释放命令提示符,后续的操作在后台完成

 

前台-->后台:

         Ctrl+z: 把正在前台的作业送往后台,处于停止状态

         COMMAND &:让命令在后台执行

        

bg: 让后台的停止作业继续运行

         bg [[%]JOBID]

 

jobs: 查看后台的所有作业

         作业号不同于进程号

                   +:命令默认将操作的作业

                    -:命令第二个默认将操作的作业

                  

fg: 将后台的作业调回前台

         fg [[%]JOBID]

        

kill %JOBID: 终止某作业

 

vmstat:系统状态查看命令

vmstat [ interval [ count ] ]
[ procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 0  0  85348 213456 363980 818276    0    0     0     1    1    2  0  0 100  0  0

 

各字段分别表示:

运行队列长度,阻塞队列长度, swap,空闲,buff, cache, si: swap in, so : swap out, bi: block in, bo block out, in: interrept 个数,cs: context switch, us: 用户空间占用CPU时间百分比, sy: 内核空间, id: 空闲, wa: 等待IO

 

 

 

 

转载于:https://www.cnblogs.com/huhyoung/p/8910106.html

你可能感兴趣的:(马哥学习笔记)