文件系统访问列表:

tom:

tom, tom基本组

jerry: other:r--

chown

FACL:Filesystem Access Control List

利用文件扩展保存额外的访问控制权限

setfacl: 设置facl

  -m: 设定额外的访问控制列表

    u:UID:perm: u代表用户,UID代表用户名,perm代表权限

    g:GID:perm: g代表组,GID代表组名,perm代表权限

    d:u:UID:perm: 设置目录默认访问控制列表,在目录下创建的文件或子目录会继承父目录的额外访问控制列表权限

    d:g:UID:perm: 设置目录默认访问控制列表,在目录下创建的文件或子目录会继承父目录的额外访问控制列表权限

  -x:取消额外的访问控制列表

    u:UID: u代表用户,UID代表用户名

    g:GID: g代表组,GID代表组名

getfacl: 获取facl

mask: 无论给来某个额外访问控制列表中的用户或者组是什么权限,但是不能超出mask给的权限的,如果超出mask中的权限位,把超出的权限全部截取消掉,默认mask会随着用户权限的增加而增加;

用户访问文件如何匹配文件安全上下文:

默认情况下当某个用户去访问某个文件的时候,用户组和权限的应用次序是什么,当某个用户去访问某个文件一定是使用某个进程来访问,这个进程的属主一定是这个用户自身,属组是这个用户的基本组,所以这个进程在访问某个文件时候,以这个用户的身份去访问的,它是怎么去应用这些权限,首先查看进程的属主跟这个文件的属主是不是一样,如果一致就应用这个文件属主访问权限,如果属主不匹配,检测这个用户是不是属于这个文件的属组,如果用户属于这个文件的属组,接下来就以组的身份来访问,如果还不是就以其他权限来访问,这是默认情况,如果使用facl额外访问控制列表,首先检测进程的属主跟文件的属主是不是一致,如果不一致就检测facl中的user,有没有某个user中用户正好跟当前进程的属主匹配,如果有就以facl中user指定的权限来访问,否则看这个用户属不属于这个文件的属组,如果没有找facl当中的某个组中的定义,如果刚好这个进程的属主属于facl当中某个组,就以facl中这个组的权限来访问,否则以other权限访问;

默认权限匹配方式:

Owner --> Group --> Other

添加facl额外访问控制列表权限匹配方式:

Owner --> facl, user --> Group --> facl, group --> Other

[root@Smoke ~]# mkdir /backup(创建/backup目录)
[root@Smoke ~]# cd /backup/(切换到/backup目录)
[root@Smoke backup]# cp /etc/inittab ./(拷贝inittab文件到当前目录)
[root@Smoke backup]# getfacl inittab(查看inittab文件的facl)
# file: inittab(文件名)
# owner: root(属主)
# group: root(属组)
user::rw-(属主权限)
group::r--(属组权限)
other::r--(其他权限)
[root@Smoke ~]# su - hadoop(切换到hadoop用户)
[hadoop@Smoke ~]$ cd /backup/(切换到backup目录)
[hadoop@Smoke backup]$ ls(查看目录文件)
inittab
[hadoop@Smoke backup]$ echo 123 > inittab(写123到inittab文件,由于其他只有读权限,所以拒绝写入)
-bash: inittab: Permission denied
[root@Smoke backup]# setfacl -m u:hadoop:rw inittab(设定hadoop用户对inittab文件有读写权限,-m设置额外访问控制列表)
[root@Smoke backup]# getfacl inittab(查看inittab文件的额外访问控制列表)
# file: inittab
# owner: root
# group: root
user::rw-
user:hadoop:rw-
group::r--
mask::rw-
other::r--
[hadoop@Smoke backup]$ echo 123 >> inittab(通过hadoop用户可以写入123到inittab文件)
[hadoop@Smoke backup]$ tail -5 inittab(查看inittab文件后5行)
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault:
123
[root@Smoke backup]# setfacl -m g:mygroup:rw inittab(设置mygroup组对inittab文件有读写权限,-m设定额外访问控制列表)
[root@Smoke backup]# getfacl inittab(查看inittab文件的额外访问控制列表)
# file: inittab
# owner: root
# group: root
user::rw-
user:hadoop:rw-
group::r--
group:mygroup:rw-
mask::rw-
other::r--
[root@Smoke backup]# setfacl -m u:hbase:rwx inittab(设置hbase用户对inittab文件有读写执行权限,-m设定额外访问控制列表)
[root@Smoke backup]# getfacl inittab(查看inittab文件的额外访问控制列表)
# file: inittab
# owner: root
# group: root
user::rw-
user:hadoop:rw-
user:hbase:rwx
group::r--
group:mygroup:rw-
mask::rwx
other::r--
[root@Smoke backup]# setfacl -x u:hadoop inittab(取消hadoop用户对inittab文件额外访问控制列表权限)
[root@Smoke backup]# getfacl inittab(查看inittab文件的额外访问控制列表)
# file: inittab
# owner: root
# group: root
user::rw-
user:hbase:rwx
group::r--
group:mygroup:rw-
mask::rwx
other::r--
[root@Smoke backup]# setfacl -x g:mygroup inittab(取消mygroup组对文件inittab文件额外访问控制列表权限)
[root@Smoke backup]# getfacl inittab(查看inittab文件的额外访问控制列表)
# file: inittab
# owner: root
# group: root
user::rw-
user:hbase:rwx
group::r--
mask::rwx
other::r--
[root@Smoke backup]# ll(查看当前目录下文件详细信息)
total 4
-rw-rwxr--+ 1 root root 888 Jul  2 23:14 inittab
提示:如果有额外访问控制列表权限位,在文件的权限位后面会多一个+加号,这表示它有扩展属性,一个有着扩展属性的文件,通过复制或其他方式,来复制一个文件来归档一个文件,很可能这个
扩展属性不会被归档的除非使用特定的选项或命令才可以;

几个命令:

w:显示当前登录到系统用户有那些,并显示它们在干什么,显示的信息比who更详细

who:显示当前登录到当前系统用户都有那些以及它所登录的终端

-a:显示所有

-r:显示当前运行级别

-H:显示字段头部

终端:对linux而言,终端指的是物理设备,用户要想登入系统,一定要么是远程借助物理设备登录,要么是借助本地显示器、键盘、鼠标登录的,所以必须要关联到某个硬件上面

终端类型:

console:控制台,直接连接到主机上的物理设备显示器和键盘,控制台和终端没有关系,控制台不是终端,它只是能够直接连进你的硬件设备一个显示界面,因为这时候还没有用户登录,压根就没有用户的相关概念,一般说终端都是可以登录的,可以验证用户身份的硬件设备,通常是软件和硬件的结合

pty:物理终端(VGA),通常指的是设备已经被识别出来了,但此前仍然没有跟用户关联的时候,通常控制台指的就是物理终端

tty#:虚拟终端(VGA),通常是附近在某个物理终端上的,而且虚拟控制台通常都在本地,通过物理终端加软件的方式模拟实现的

ttyS#:串行终端

pts/#:伪终端,ssh/telnet等等

脚本:

每隔5秒钟,就来查看hadoop是否已经登录,如登录,显示其已经登录,并退出;

sleep:让进程睡眠几秒钟,时间过后自动退出睡眠

whoami:显示当前登录系统用户

last,显示/var/log/wtmp文件,显示用户登录历史及系统重启历史

  -n #: 显示最近#次的相关信息

lastb,/var/log/btmp文件,显示用户错误的登录尝试

  -n #: 显示最近#次的相关信息

lastlog: 显示每一个用户最近一次的成功登录信息;

  -u USERNAME: 显示特定用户最近的登录信息

basename:显示路径基名/文件名

  $0: 特殊变量,执行脚本时的脚本路径及名称

mail:邮件,只能在本机上不同的用户之间进行发送

-s:在命令行直接指定邮件的主题/标题

d:删除邮件

r:回复邮件

/home/USERNAME/mbox:邮件查看完备份地方

hostname: 显示主机名

如果当前主机的主机名不是 www.magedu.com ,就将其改为 www.magedu.com

[root@Smoke ~]# [ `hostname`  != ' www.magedu.com ' ] && hostname www.magedu.com
[root@Smoke ~]# hostname
www.magedu.com

如果当前主机的主机名是localhost,就将其改为 www.magedu.com

[root@Smoke ~]# [ `hostname` == 'localhost' ] && hostname www.magedu.com

如果当前主机的主机名为空,或者为(none),或者为localhost,就将其改为 www.magedu.com

[ -z `hostname` ] || [ `hostname` == '(none)' -o `hostname` == 'localhost' ] && hostname www.magedu.com

生成随机数

RANDOM: 0-32768,环境变量

随机数生成器:熵池

/dev/random:软件模拟设备,有规律,容易被攻破,会阻塞用户进程,更安全

/dev/urandom:软件模拟设备,有规律,容易被攻破,不会阻塞用户进程

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

#!/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
[root@Smoke ~]# whoami(显示当前登录系统的用户)
root
[root@Smoke ~]# who(显示登录到当前系统用户都有那些以及它所登录的终端)
root     pts/0        2014-07-03 22:20 (172.16.100.254)
[root@Smoke ~]# su - hadoop(切换到hadoop用户)
[hadoop@Smoke ~]$ whoami(查看当前登录系统用户)
hadoop
[root@Smoke ~]# who | grep "hadoop"(查看hadoop用户有没有登录进来)
提示:使用su切换到用户,虽然whoami显示有效用户id,但是这个用户并非是登录用户
Xshell:\> ssh 172.16.100.1(使用hadoop用户登录)
Connecting to 172.16.100.1:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
Last login: Thu Jul  3 22:55:42 2014 from 172.16.100.254
[hadoop@Smoke ~]$
[root@Smoke ~]# who | grep "hadoop"(查看hadoop用户有没有登录进来)
hadoop   pts/2        2014-07-03 22:55 (172.16.100.254)
[root@Smoke ~]# sleep 3(让进程睡3秒钟,3秒过后自动退出睡眠)
[root@Smoke ~]# w(显示当前登录系统的用户有那些,并显示它们在干什么)
23:03:58 up 44 min,  3 users,  load average: 0.00, 0.01, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    172.16.100.254   22:20    0.00s  0.08s  0.01s w
root     pts/1    172.16.100.254   22:54    9:11   0.02s  0.01s -bash
hadoop   pts/2    172.16.100.254   22:57    6:28   0.00s  0.00s -bash
[root@Smoke ~]# last(显示用户登录历史及系统重启历史)
hadoop   pts/2        172.16.100.254   Thu Jul  3 22:57   still logged in  
hadoop   pts/2        172.16.100.254   Thu Jul  3 22:55 - 22:56  (00:01)    
root     pts/1        172.16.100.254   Thu Jul  3 22:54   still logged in  
root     pts/0        172.16.100.254   Thu Jul  3 22:20   still logged in  
reboot   system boot  2.6.32-431.11.2. Thu Jul  3 00:31 - 23:06  (22:34)    
root     pts/4        172.16.100.254   Wed Jul  2 23:05 - 00:08  (01:03)    
root     pts/0        172.16.100.254   Wed Jul  2 22:57 - 00:08  (01:11)  
[root@Smoke ~]# last -n 3(只显示最近3此用户登录历史及系统重启历史)
hadoop   pts/2        172.16.100.254   Thu Jul  3 22:57   still logged in  
hadoop   pts/2        172.16.100.254   Thu Jul  3 22:55 - 22:56  (00:01)    
root     pts/1        172.16.100.254   Thu Jul  3 22:54   still logged in  
wtmp begins Mon Apr 14 08:39:43 2014
[root@Smoke ~]# lastb(显示用户错误的登录尝试)
btmp begins Tue Jul  1 16:28:02 2014
[root@Smoke ~]# lastlog(显示每一个用户最近一次的成功登录信息)
Username         Port     From             Latest
root             pts/1    172.16.100.254   Thu Jul  3 22:54:41 +0800 2014
bin                                        **Never logged in**
daemon                                     **Never logged in**
adm                                        **Never logged in**
lp                                         **Never logged in**
sync                                       **Never logged in**
shutdown                                   **Never logged in**
halt                                       **Never logged in**
mail                                       **Never logged in**
[root@Smoke ~]# lastlog -u hadoop(显示hadoop用户最近一次成功登录信息)
Username         Port     From             Latest
hadoop           pts/2    172.16.100.254   Thu Jul  3 22:57:30 +0800 2014
[root@Smoke ~]# basename /etc/abrt/me(显示路径基名/文件名)
me
[root@Smoke ~]# vim showshells.sh(编辑showshels.sh文件)
#!/bin/bash
#
if [ $1 == '-s' ];then
 ! grep "${2}$" /etc/shells /etc/shells &> /dev/null && echo "Invalid shell." && exit 7
elif [ $1 == '--help' ];then
 echo "Usage: `basename $0` -s SHELL | --help"
 exit 0
else
 echo "Unknown Options."
 exit 8
fi
NUMOFUSER=`grep "${2}$" /etc/passwd | wc -l`
SHELLUSERS=`grep "${2}$" /etc/passwd | cut -d: -f1`
SHELLUSERS=`echo $SHELLUSERS | sed 's@[[:space:]]@,@g'`
echo -e "$2, $NUMOFUSER users, they are: \n$SHELLUSERS"
[root@Smoke ~]# ./showshells.sh --help(当前目录执行showshells.sh文件)
Usage: showshells.sh -s SHELL | --help
[root@Smoke ~]# mail(收邮件)
Heirloom Mail version 12.4 7/29/08.  Type ? for help.
"/var/spool/mail/root": 1 message 1 new
>N(新邮件)  1(第一封邮件) Anacron(谁发过来的)               Tue Apr 15 20:14(发送时候)  17/626   "Anacron job 'cron.daily' on Smoke"(邮件主题)
& 1(查看邮件,将邮件编号写到这里)
& q(退出邮件)
[root@Smoke ~]# cat /etc/fstab | mail -s "How are you?" root(将fstab文件内容发送给用户root,-s指定主题)
[root@Smoke ~]# mail(查看邮件)
Heirloom Mail version 12.4 7/29/08.  Type ? for help.
"/var/spool/mail/root": 2 messages 1 new
   1 Anacron               Tue Apr 15 20:14  18/637   "Anacron job 'cron.daily' on Smoke"
>N  2 root                  Fri Jul  4 00:00  32/1380  "How are you?"
&
[root@Smoke ~]# mail -s "How are you?" root < /etc/fstab(将fstab文件内容发送给用户root,-s指定主题)
[root@Smoke ~]# mail(查看邮件)
Heirloom Mail version 12.4 7/29/08.  Type ? for help.
"/var/spool/mail/root": 3 messages 1 new 2 unread
   1 Anacron               Tue Apr 15 20:14  18/637   "Anacron job 'cron.daily' on Smoke"
U  2 root                  Fri Jul  4 00:00  33/1390  "How are you?"
>N  3 root                  Fri Jul  4 00:01  32/1380  "How are you?"
&
[root@Smoke ~]# hostname(显示主机名)
Smoke
[root@Smoke ~]# echo $HOSTNAME(显示主机名)
Smoke
[root@Smoke ~]# hostname www.smoke.com (更改主机名)
[root@Smoke ~]# hostname(显示主机名)
www.smoke.com
[root@Smoke ~]# echo $HOSTNAME(显示主机名)
Smoke
[root@Smoke ~]# [ `hostname`  != ' www.magedu.com ' ] && hostname www.magedu.com (当主机名不等于 www.magedu.com 就执行更改为 www.magedu.com )
[root@Smoke ~]# hostname(查看主机名)
www.magedu.com [root@Smoke ~]# hostname localhost(更改主机名为localhost)
[root@Smoke ~]# hostname(查看主机名)
localhost
[root@Smoke ~]# hostname '(none)'(更改主机名为(none))
[root@Smoke ~]# hostname(查看主机名)
(none)
[root@Smoke ~]# [ -z `hostname` ] || [ `hostname` == '(none)' -o `hostname` == 'localhost' ] && hostname www.magedu.com (判断主机名是否为空或者为
(none)或者localhost,则更改为 www.magedu.com )
[root@Smoke ~]# hostname(查看主机名)
www.magedu.com
[root@Smoke ~]# hostname ''(更改主机名为空)
[root@Smoke ~]# hostname(查看主机名)
[root@Smoke ~]# [ -z `hostname` ] || [ `hostname` == '(none)' -o `hostname` == 'localhost' ] && hostname www.magedu.com (判断主机名是否为空或者为
(none)或者localhost,则更改为 www.magedu.com )
[root@Smoke ~]# hostname(查看主机名)
www.magedu.com
[root@Smoke ~]# echo $RANDOM(生成随机数)
27257

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

#!/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
[root@Smoke ~]# for I in {1..10}; do echo -n "$RANDOM,"; echo -e "\n"; done(执行10次循环,不换号显示$RANDOM,再通过空白换行)
13759,
7947,
3940,
3503,
30632,
25783,
26250,
29207,
19999,
28854,
[root@Smoke ~]# vim random.sh(编辑random.sh文件)
#!/bin/bash
#
for I in {1..10};do
 if [ $I -le 9 ];then(当$I小于9为真执行不换行显示$RANDOM,,否则就直接显示$RANDOM)
       echo -n "$RANDOM,"
 else
       echo "$RANDOM"
 fi
done
[root@Smoke ~]# chmod +x random.sh(给random.sh文件执行权限)
[root@Smoke ~]# ./random.sh(当前目录执行random.sh文件) 25266,18498,32531,19363,23142,4408,4692,22236,3841,7949 [root@Smoke ~]# vim random.sh(编辑random.sh文件) #!/bin/bash # declare -i MAX=0(声明MAX为整数,并且赋值为0) for I in {1..10};do MYRAND=$RANDOM(声明变量MYRAND,并赋值为$RANDOM) if [ $I -le 9 ];then echo -n "$MYRAND," else echo "$MYRAND" fi [ $MYRAND -gt $MAX ] && MAX=$MYRAND(当$MYRAND大于$MAX就将$MYRAND值赋予MAX变量) done echo $MAX [root@Smoke ~]# ./random.sh(当前目录执行random.sh文件) 26922,24391,27149,8436,7829,18608,19031,16121,27906,8734 27906 [root@Smoke ~]# vim random.sh(编辑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(当$I等于1时,将$MYRAND的值赋予MIN变量) 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 [root@Smoke ~]# ./random.sh(当前目录执行random.sh文件) 16129,24025,24509,29752,2837,6807,24061,17168,205,20830 29752, 205

面向过程

  控制结构

    顺序结构

    选择结构

    循环结构

选择结构:

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

if CONDITION; then

  statement

  ...

fi

if CONDITION; then

  statement

  ...

else

  statement

  ...

fi
if CONDITION1; then

  statement

  ...

elif CONDITION2; then

  statement

  ...

esle

  statement

  ...

fi

多分支if语句执行效率比较低,需要逐个条件进行比较

case语句:选择结构(多分支)

case SWITCH(引用变量值) in

value1)(变量值为value1,value被当作字符来做比较)

  statement(执行语句1)

  ...

  ;;(双分号结尾)

value2)(变量值为value2,value被当作字符来做比较)

  statement(执行语句2)

  ...

  ;;(双分号结尾)

*)(其他可能性,类似与if语句中的else)

  statement(执行语句3)

  ...

  ;;(双分号结尾)

esac(case反过来结尾)

字符中的表达式,在value中都可以使用

a-z

A-Z

0-9

[abc]

只接受参数start,stop,restart,status其中之一

#!/bin/bash
#
case $1 in
'start')
       echo "start server..."
       ;;
'stop')
       echo "stop server..."
       ;;
'restart')
       echo "Restarting server..."
       ;;
'status')
       echo "Running..."
       ;;
*)
       echo "`basename $0` (start|stop|restart|status)"
       ;;
esac

在一个脚本,可以接受选项及参数,而后能获取每一个选项,及选项的参数;并能根据选项及参数做出特定的操作,比如:adminusers.sh --add tom,jerry --del tom,blair -v|--verbase -h |--help

#!/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
[root@Smoke ~]# vim case.sh(编辑case.sh文件)
#!/bin/bash
#
case $1 in
[a-z]*)($1为小写字母时显示为小写)
       echo "Lower."
       ;;
[A-Z]*)($1为大写字母时显示为大写)
       echo "Upper."
       ;;
[0-9]*)($1为数字时显示为数字)
       echo "A digit."
       ;;
*)(其他字符认为是特殊字符)
       echo "Special character."
       ;;
esac
[root@Smoke ~]# chmod +x case.sh(给case.sh执行权限)
[root@Smoke ~]# ./case.sh F(当前目录执行case.sh)
Upper.
[root@Smoke ~]# ./case.sh f(当前目录执行case.sh)
Lower.
[root@Smoke ~]# ./case.sh 2(当前目录执行case.sh)
A digit.
[root@Smoke ~]# vim service.sh(编辑service.sh文件)
#!/bin/bash
#
case $1 in
'start')
       echo "start server..."
       ;;
'stop')
       echo "stop server..."
       ;;
'restart')
       echo "Restarting server..."
       ;;
'status')
       echo "Running..."
       ;;
*)
       echo "`basename $0` (start|stop|restart|status)"
       ;;
esac
[root@Smoke ~]# chmod +x service.sh(给service.sh执行权限)
[root@Smoke ~]# ./service.sh start(当前目录执行service.sh文件)
start server...
[root@Smoke ~]# vim debug.sh(编辑debug.sh文件)
#!/bin/bash
#
DEBUG=0
case $1 in
-v|--verbose)
       DEBUG=1
       ;;
*)
       echo "Unknown options"
       exit 7
       ;;
esac
[ $DEBUG -eq 1 ] && echo hello
[root@Smoke ~]# chmod +x debug.sh(给debug.sh执行权限)
[root@Smoke ~]# ./debug.sh --verbose(当前目录执行debug.sh文件)
hello
[root@Smoke ~]# vim adduser.sh(编辑adduser.sh文件)
#!/bin/bash
#
DEBUG=0
case $1 in
-v|--verbose)
       DEBUG=1
       ;;
esac
useradd tom &> /dev/null
[ $DEBUG -eq 1 ] && echo "Add user tom finished."
[root@Smoke ~]# chmod +x adduser.sh(给adduser.sh执行权限)
[root@Smoke ~]# ./adduser.sh -v(当前目录执行adduser.sh文件)
Add user tom finished.
[root@Smoke ~]# vim adminusers3.sh(编辑adminusers3.sh文件)
#!/bin/bash
#
DEBUG=0
ADD=0
DEL=0
for I in `seq 0 $#`;do
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
       USERS=$2
       shift 2
       ;;
--del)
       DEL=1
       USERS=$2
       shitf 2
       ;;
*)
       echo "Usage:`basename $0` --add USER_LIST --del USER_LIST -v|--verbose -h|--help"
       exit 7
       ;;
esac
done
       echo $DEBUG $ADD $DEL
[root@Smoke ~]# chmod +x adminusers3.sh(给adminusers3.sh执行权限)
[root@Smoke ~]# bash -x adminusers3.sh -v --add(显示adminusers3.sh文件执行过程)
+ DEBUG=0
+ ADD=0
+ DEL=0
++ seq 0 2
+ for I in '`seq 0 $#`'
+ case $1 in
+ DEBUG=1
+ shift
+ for I in '`seq 0 $#`'
+ case $1 in
+ ADD=1
+ USERS=
+ shift 2
+ for I in '`seq 0 $#`'
+ case $1 in
+ ADD=1
+ USERS=
+ shift 2
+ echo 1 1 0
1 1 0
[root@Smoke ~]# bash -x adminusers3.sh -v --add user1,user2 --del(显示adminuser3.sh文件执行过程)
+ DEBUG=0
+ ADD=0
+ DEL=0
++ seq 0 4
+ for I in '`seq 0 $#`'
+ case $1 in
+ DEBUG=1
+ shift
+ for I in '`seq 0 $#`'
+ case $1 in
+ ADD=1
+ USERS=user1,user2
+ shift 2
+ for I in '`seq 0 $#`'
+ case $1 in
+ DEL=1
+ USER=
+ shitf 2
adminusers3.sh: line 24: shitf: command not found
+ for I in '`seq 0 $#`'
+ case $1 in
+ DEL=1
+ USER=
+ shitf 2
adminusers3.sh: line 24: shitf: command not found
+ for I in '`seq 0 $#`'
+ case $1 in
+ DEL=1
+ USER=
+ shitf 2
adminusers3.sh: line 24: shitf: command not found
+ echo 1 1 1
1 1 1
[root@Smoke ~]# bash -x adminusers3.sh --help
+ DEBUG=0
+ ADD=0
+ DEL=0
++ seq 0 1
+ for I in '`seq 0 $#`'
+ case $1 in
++ basename adminusers3.sh
+ echo 'Usage:adminusers3.sh --add USER_LIST --del USER_LIST -v|--verbose -h|--help'
Usage:adminusers3.sh --add USER_LIST --del USER_LIST -v|--verbose -h|--help
+ exit 0
[root@Smoke ~]# vim adminusers3.sh(编辑adminusers3.sh文件)
#!/bin/bash
#
DEBUG=0
ADD=0
DEL=0
for I in `seq 0 $#`;do(执行循环次数为参数个数)
case $1 in
-v|--verbose)(当第一个参数等于-v或者--verbose时,让DEBUG值为1,并且剔除第一个参数-v或者--verbose)
       DEBUG=1
       shift
       ;;
-h|--help)(当第一个参数等于-h或者--help时,显示使用方法,并退出脚本)
       echo "Usage:`basename $0` --add USER_LIST --del USER_LIST -v|--verbose -h|--help"
       exit 0
       ;;
--add)(当第一个参数等于-add时,让ADD的值等于1,并且让ADDUSERS值等于第二个参数,踢出前2个参数)
       ADD=1
       ADDUSERS=$2
       shift 2
       ;;
--del)(当第一个参数等于--del时,让DEL值等于1,并且让DELUSERS值等于第二个参数,踢出前2个参数)
       DEL=1
       DELUSERS=$2
       shift 2
       ;;
#*)(其他情况显示脚本使用方法,并退出,返回状态返回值为7)
#        echo "Usage:`basename $0` --add USER_LIST --del USER_LIST -v|--verbose -h|--help"(basename $0特殊变量引用脚本文件名)
#        exit 7
#        ;;
esac    
done      
if [ $ADD -eq 1 ];then(判断$ADD是否等于1,如果等于1,则执行for循环,变量USER值为$ADDUSERS值去掉,逗号空格隔开的第一个字符串)
for USER in `echo $ADDUSERS | sed 's@,@ @g'`;do
if id $USER &> /dev/nulll;then(判断用户是否存在,如果存在,就执行判断$DEBUG是否等于1,如果等于就执行显示用户存在,否则就添加用户,如果$DEBUG等于1就执行添加用户完成)
       [ $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(判断$DEL是否等于1,如果等于1就执行for循环,让$USER的值等于$DELUSERS的值将,逗号替换成空格的第一个字符串)
for USER in `echo $DELUSERS | sed 's@,@ @g'`;do
if id $USER &> /dev/nulll;then(判断$USER用户是否村子,如果参照就执行删除用户,当$DEBUG等于1就显示用户删除完成,否则执行当$DEBUG等于1就显示用户不存在)
       userdel -r $USER
       [ $DEBUG -eq 1 ] && echo "Delete $USER finished."
else
       [ $DEBUG -eq 1 ] && echo "$USER not exist. "
fi
done
fi
[root@Smoke ~]# ./adminusers3.sh -v --del tom,jerry,natasha(当前目录执行adminusers3.sh文件)
tom not exist.
jerry not exist.
natasha not exist.

在一个脚本,可以接受选项及参数,而后能获取每一个选项,及选项的参数;并能根据选项及参数做出特定的操作,比如:adminusers.sh --add tom,jerry --del tom,blair -v|--verbase -h |--help

#!/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

练习:写一个脚本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
[root@Smoke ~]# vim showlogged.sh(编辑showlogged.sh文件)
#!/bin/bash
#
declare -i SHOWNUM=0(声明SHOWNUM为整数并且等于0)
declare -i SHOWUSERS=0(声明SHOWUSERS为证书并且等于0)
for I in `seq 1 $#`;do(执行for循环,执行参数个数次)
if [ $# -gt 0 ];then(判断参数个数是否大于0,如果大于就执行)
case $1 in
-h|--help)(当第一个参数等于-h或者--help时,就执行显示脚本使用帮助,并正常退出,返回正常状态返回值)
       echo "USage: `basename $0` -h|--help -c|--count -v|--verbose"
       exit 0
       ;;
-v|--verbose)(当第一个参数等于-v或者--verbose就执行将SHOWUSERS等于1,并剔除第一个参数)
       let SHOWUSERS=1
       shift
       ;;
-c|--count)(当第一个参数等于-c或者--count就执行将SHOWNUM等于1,并踢出第一个参数)
       let SHOWNUM=1
       shift
       ;;
*)(其他情况执行显示脚本使用方法,并退出,返回错误状态返回值)
       echo "USage: `basename $0` -h|--help -c|--count -v|--verbose"
       exit 8
       ;;
esac
fi
done
if [ $SHOWNUM -eq 1 ];then(当$SHOWNUM等于1就执行显示who | wc -l用户连接个数)
       echo "Logged users:`who | wc -l`."
fi
if [ $SHOWUSERS -eq 1 ];then(当$SHOWUSERS等于1就执行显示用户链接)
       echo "They are:"
       who
fi
[root@Smoke ~]# chmod +x showlogged.sh(给showlogged.sh执行权限)
[root@Smoke ~]# ./showlogged.sh -c -v(当前目录执行showlogged.sh文件)
Logged users:2.
They are:
root     pts/1        2014-07-06 16:17 (172.16.100.254)
root     pts/2        2014-07-06 17:40 (172.16.100.254)
[root@Smoke ~]# vim showlogged.sh(编辑showlogged.sh文件)
#!/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(当SHOWNUM等于1就执行显示用户链接个数,再执行判断$SHOWUSER等于1就执行用户链接信息)
       echo "Logged users:`who | wc -l`."
if [ $SHOWUSERS -eq 1 ];then
       echo "They are:"
       who
fi
fi
[root@Smoke ~]# ./showlogged.sh -c -v(当前目录执行showlogged.sh文件)
Logged users:2.
They are:
root     pts/1        2014-07-06 16:17 (172.16.100.254)
root     pts/2        2014-07-06 17:40 (172.16.100.254)

磁盘管理:

机械式硬盘:

  U盘(闪存存储设备)、光盘、软盘、硬盘、磁带

磁盘的物理组成:

1、盘片(Platters)

2、轴(Spindle)

3、读写头(Read/Write Head)

4、读写头激励器(Actuator)

5、控制器(Controller)

磁盘的结构:

1、Actuator Arm Assembly

2、扇区(Sector)与磁道(Track)

磁盘的内部的盘片有很懂的磁道,读写头在读写数据的时候盘片上排列很多紧密的磁性材料,而读写数据是靠盘片不停的旋转来完成的,磁头分别划过不同的位置来获取数据,所以盘面都划分成不同的同心圆,存数据也是按照同心圆的存储的,这些同心圆叫做磁道,磁道从外向内整个周长是不一样的,外面的磁道比里面的磁道能够存储更多的数据,所以不能说存储一个数据是按磁道来划分,为了能够便于实现数据管理,磁道上的存储空间是划分成扇区(Sector)的,扇区用户存储用户的数据,并且包含扇区自己的编号,磁头号、碟片号、磁道号等等,每一个扇区上都有存储,所以扇区在存储数据时候,本来是512字节,很可能只有500字节用于拿来存储数据,后面12个字节都是额外开销,要用于存储额外数据,一般而言,每一个扇区的大小是512bytes,整个硬盘是按照在一个轴固定下同步旋转的,所以存数据是分散存储在多个盘面上,位于不同盘面上的相同编号的磁道称为Cylinder(柱面),在使用硬盘要划分分区,如果不划分分区意味着整个磁盘只能存储一个文件系统,如果划分了分区,每一个分区都可以是一个独立的文件系统,分区其实是磁盘的逻辑边界,磁盘的分区信息保存在那,磁盘刚出厂的时候在厂商会做一次格式化,这种格式化是低级格式化,低级格式化用来划分磁道的,但是里面没有任何分区;

低级格式化:用来划分磁道,里面没有任何分区

分区(Partition):把磁盘划分成不同的逻辑组成结构,每一个组成结构可以创建一个文件系统,分区是用来创建独立的文件系统

MBR:Master/Main Boot Reccord主引导记录(512byte),MBR是属于磁盘的,属于全局的,不是被操作系统所使用的,独立在操作系统之外的存储空间,在这512byte划分为3个片段;

MBR空间划分为3个片段:

446bytes:BootLoader(程序),引导加载器,能够完成引导某个分区上的操作系统启动起来

64bytes:

16bytes:每16byte标识一个分区,一共可以表示4个分区,所以硬盘只能划分4个主分区,

2bytes:Magic Number(魔数)

标记MBR是否有效

当电脑开机的时候,内存是空的,CPU中所读的数据是来自于内存的,BIOS中的数据,BIOS是存在在ROM中的一段程序代码,这段程序代码能够完成电脑自身健康状况的检测,BIOS中设定了如何检查自身的健康状况,BIOS只是一段程序,这段程序在开机以后会直接把ROM芯片中的内容映射到内存中最开始的一段空间中来,所以一开机CPU就试图去加载内存最低端里面的代码,这段代码刚好是BIOS,接下来执行BIOS指令,BIOS指令执行完成以后,发现没问题了,接下来就去根据BIOS中设定的启动次序挨个去找启动设备的MBR,第一个启动设备如果是光盘,就去找有没有光盘设备,如果有光盘设备就去找MBR,如果光盘没有MBR,就找第二个设备的,如果光盘有MBR但是MBR坏了,系统就开始抱错了,提示启动不了,不是说第一个出现错误就会启动第二个,而是第一个没有MBR的时候才会找第二个,如果第一个光盘没有MBR就去找第二个,第二个恰好使我们的硬盘,开始读取硬盘的MBR,硬盘中前446bytes叫做BootLoader(引导加载器),又是一段代码,于是BIOS这段程序就把BootLoader加载到内存,这段程序要相应读取我们的分区表,而后这段程序试图根据我们的配置去加载对应的分区上的操作系统,因此这段程序必须要能读取我们的分区表,如果没有分区表就找不到操作系统,所以BootLoader被加载进来以后,BIOS就退出了,BIOS把执行的指令告诉CPU,接下来执行这段BootLoader,于是BootLoader一运行,根据我们所选择的操作系统,他会找到特定的分区,在其中某个分区有操作系统,BootLoader就会到对应分区上去找操作系统的内核,于是BootLoader就会把操作系统的内核读进内存里面来,当内核读取进来并解压缩完成以后,而后BoootLoader将控制器交给内核,于是内核开始启动自身,接着根据文件配置找到文件系统在什么地方,找到所需要运行的每一个程序,最终操作系统启动完成;

扩展分区:虽然只能有4个主分区,但是可以拿一个分区出来不真正用来创建分区,它指向磁盘上的另外一个位置,这里只有64bytes,空间很小,拿出来16个字节,这个字节里面没有存储分区信息,而存储的是指针,指向磁盘上另外一个更大的空间里面,告诉你里面还有分区信息,所以在那个更大的空间里面可以存储更多的信息,而这个分区叫做扩展分区

主+扩展<=4

在一个硬盘扩展分区只能有一个

磁道越靠外读写速率越高,应该把经常访问的数据放到最外面的磁道上,比如操作系统

Metadate:元数据

文件系统:按名存储文件快速存储文件,管理软件,存储在磁盘某个位置,文件系统并不在分区上,但是文件系统数据在这个分区上;

磁盘分区:

分区上可以存储很多数据,其实就是磁盘的存储空间,于是我们的01代码可以一行一行使劲的存都没问题,但是如果我想要在这个分区上存储三个文件a、b、c,如何知道a文件存在那个位置,b文件存储在那个位置,以及c文件存储在那个位置,将来要访问三个文件去那里找,直接在上面存数据,挨个存,a存完了后面还有空余空间,继续存储b文件,然后继续存储c文件,下次再找文件会发现磁盘数据无非是0101一串代码而已,如何知道那一段是a文件结束了,哪一段是b文件开始,如何得知,无从得知,因为对整个磁盘来讲里面无法就是存01代码而已,它如何知道这是a文件,这是b文件,那个是c文件,况且这个文件有没有名,名跟数据没有关系,必须要对里面存储的数据给它一些逻辑的边界,从那个地方起始到那个地方结束,能够有一个寻址定位的方法,于是我们的磁盘分区就应该被划分为两个阶段,把a b c三个文件存储上去要找其中一个文件,需要一位一位检查,每一次访问都是这样子,得遍历整个所有文件,太困难了,为了加速查找检索,先分类再编号,再建立查找索引,给每个文件分类再编号,对每个文件建立一个索引,要找某个文件,先看看索引,索引里面会写这个文件在那些地方,因此要有其中这个文件名字是什么,第二这个对应的文件存储在什么位置,需要有一个对应文件存储的路径,而后先找到编目,再找到对应的目录,根据这个路径再实际的去找文件就快的多了,如果磁盘非常大,里面存储很多的文件,从这些编目里面找一个文件名也很困难,再划分不同的分区,编码跟文件没有关系,编目是用来存储文件快速查找的检索的位置,所以可以称为索引,所以称为元数据,只是为了能检索文件,标识文件,这样一些数据,叫做Metdate(元数据),对文件的快速存取,这就是文件系统的意义,创建完分区以后要能够实现按名存储文件快速存储文件,要在分区上创建叫文件系统,文件系统是一个软件,它也是存储在磁盘上的某个位置,并不是直接在这个分区上,但是文件系统的数据在这个分区上,可以认为文件系统是一个管理软件,文件系统能够把一个分区整个存储空间划分成两片,第一片叫元数据存储区,另一片是数据存储区,而数据存储区划分成一个个的逻辑存储单元,这个存储单元叫做Block(磁盘块),这也是逻辑概念,不是物理概念,是文件系统为了完成自我管理的一种概念,因此要存储一个文件,当存储一个文件,这个文件叫什么名字,放到编目,这些数据存储在那些块上,对应那些块,每个块都有编号,于是要再访问这个文件直接访问对应的编目中的编号对应的块,就可以找到其中的数据;存储区有很多的磁盘块,那些磁盘块已经使用过了,那些磁盘块是空闲的,要新建一个文件,要分配一些磁盘块,系统如何知道那些块是使用的,那些是空闲的,假设每个块有一个标记,如果标记为1就代表用过,如果没用过就标记为0,因此,要存储第二个文件,要找空闲磁盘块,就可以扫描整个磁盘分区,那个为0就找出来,找出足够个磁盘块来存储第二个文件,如果这个分区特别大,而每个块只有几k大小,要找出空闲的磁盘块会很慢,因此要找到一个空闲磁盘块就要遍历整个分区,事实上在元数据区域有一个区域叫做bitmap(块位图),它在里面划分出一段区域,这段区域为每一个块有一个对应的位,如果这个块用过了,就把对应标记符集中的放到这个区域里面,将来再找空闲磁盘块就就扫描这段区域,找那些位图为0的,而后把那些位图为0对应的块找出来,肯定就是空闲块,所谓位图就是每一个块在索引里面有一个对应的位,存储为1表示块用过了,存储块为0表示块没用过,所以再找空闲磁盘块直接扫描这个图就可以了,不用再扫描分区了,它是能够加速查找空闲磁盘块的一种机制,每存一个文件都要在元数据区域建立一个条目给这个文件,这个条目保存文件名字和文件对应数据所存储的路径,这个路径也需要占用空间,路径存储多了也会占据很多空间,在元数据区域事先指定了一些固定区域来存储对应的条目的,如果存储太多的小文件把条目中的空间占满了,数据空间还有空闲空间,里面就不能存文件了,所以条目空间需要和数据空间匹配才行,每一个文件都需要占用一个条目,新建一个文件就需要在条目空间新分配一段空间来存储对应的信息,如何知道条目空间里面有那些信息是空闲的,那些已经被占用了,当需要新建一个文件的时候,删除一个文件里面就空闲出来一个,新建就占据一个,所以过一段时间会发现里面存储的文件并不是紧密排列的,是成为碎片化的,所以要到里面找一个空闲的并且往里面新建一个怎么找到这个空闲的,也需要去扫描整个条目这段空间,这种扫描也比较慢,所以也需要给他拿出一段空间创建一段位图,所以要查看那些条目空间中的信息是空闲还是占用,只需要扫描这个位图就可以了,位图跟对应的条目是一一对应的,所以只要位图是空闲的对应的条目就是空闲的,而这里面每一个条目有一个独特的称呼叫inode(indexnode索引节点),每一个inode有一个全局唯一的编号跟用户的ID号一样,每一个inode对应唯一的号码用来引用对应的文件,inode里面标识有inode号、有对应文件的权限、属主属组、扩展属性、时间戳、大小以及它所存储磁盘块信息等各种元数据,跟文件数据没有关系的信息,就是没有文件名,如果存储一个文件,这样对应的条目里面,它要指向这个文件对应的磁盘块,如果这个文件只占据两个磁盘块很容易标识,如果一个文件特别大,它需要占据成千上万的磁盘块,所以inode要标识1w个磁盘块,它压根没有那么大的空间,那怎么办,在指向磁盘块的时候它可以使用指针,跟扩展分区一样,还有间接磁盘块指向路径,就是分级指向,它可以引用许许多多,可以扩展到其他位置来标识所占据的额外磁盘块,所以有间接目录,有二级间接目录,还有三级间接目录,用于指定磁盘块在什么位置,因此,这个条目里面无论是直接还是间接能够引用多少磁盘块决定单个文件最多能够有多大,某一个文件系统所能够支持单个文件有多大事实上对于文件系统还是至关重要的,一个基本衡量标准,尤其要清楚将来存的文件可能扩展到多大,这很关键,文件名在什么地方放,目录也是文件,在linux上所有的文件从根开始,根在什么地方,内核在启动操作系统的时候,内核会知道根在什么地方,所以内核会自己引用到根,因此根是自引用的,根一定能找到自己,所以我们能找到根,根下的文件也都能找到了,文件名在什么地方放,文件名其实在目录里面放,目录也是个文件,所以目录也需要占据磁盘块,目录占据的磁盘块里面放的是什么,目录不是容器,目录也是个磁盘块,在目录磁盘块里面存储的信息分成两段,或者是个表,第一段是inode号码,第二段是这个目录对应的它下面可以直接找到的文件名,比如;要找/var/log/messages文件,需要先去找根,根是自引用的,每一个文件在编目都有一个对应的条目,所以找到根,通过这个条目找到根所对应的磁盘块,在里面找到磁盘块里面有对应根下面的有var的文件名,在里面有一个对应的表,里面会写var这个文件对应的inode号,找到inode号码再返回条目区域空间查找表,找到对应的号码对应的条目,根据这个条目又找到磁盘块,这个磁盘块里面又存储一个表,这个表里面放的是log和log对应的inode号码,根据这个号码再回来查找条目区域中的条目表,于是就找到了Log对应磁盘块中的目录,于是再找到这个磁盘块,磁盘块里面放的又是张表,于是再查这张表,里面放的是message和对应的inode号码,根据message号码再回过头来继续找条目区域条目表,找到message所对应的条目,这个条目里面放有message这个文件占据那些磁盘块,于是数据得到访问。

如果文件的路径非常长的话,需要一定时间,如果一个文件需要多次访问的话,如果每次都这样转一大圈,效率比较低,第一次是查找,查找到以后就进行缓存,以后再找就直接到缓存中找
dentry:目录项,目录条目,目录中对应的文件名条目

创建一个文件的过程:

想新建一个/backup/test.txt文件,而这个文件中需要保存10K的数据,每个磁盘块假如是2K,首先要确保/backup目录得存在,不存在的话对应条目建立不了,这就是为什么没有目录,没办法往目录建立文件的原因,假设/backup目录是存在的,首先扫描inode表的位图,找到空闲的inode,于是把这个号占用了,接着找到/backup目录所对应的磁盘块,这个目录的磁盘块,先找到这个目录的inode,再找inode对应的磁盘块,在块里面找到对应的表,在这个表里面建立一个新的条目叫test.txt名,再将查找到的inode号码放到表里面,而后要往文件里面存储数据,找空闲磁盘块,往里面存数据,扫描块位图,假设先给它分8个磁盘块,每一个块2K,于是5个磁盘块就完了,5个占完以后发现还有3个是空闲的,直接把它归到没有使用的列表中去,为什么一下要占据那么多,为了避免文件碎片,如果用一个磁盘块分一个磁盘块,假如正好交替存储两个文件,会出现a一个块、b一个块、a一个块、b一个块...;a和b两个文件交叉存放,将来要访问文件a,得跳着去访问,这样在磁盘上速度是非常慢的,所以尽可能将磁盘上的文件,一个文件的磁盘块是连续的,长久以后磁盘总然是会出现碎片的,创建文件、删除文件、创建文件、删除文件;过段时间会发现有些磁盘块空闲都是非连续的,再存一个文件在磁盘上跳一个的存,一访问一个文件速度慢死了;

删除一个文件的过程:

删除文件很简单,第一只需要将目录当中对应的条目给它删除,第二把对应条目的inode号码在位图中标记为空,再存文件只要把它覆盖掉就可以了,不用清里面数据,只需要把它标记为空,如果存储这个文件占据了很多磁盘块,比如占据了5个磁盘块,这5个磁盘块可以腾出来存储其他文件,在块位图把磁盘块重新标记为未使用,里面数据没动,再往里面存储新文件只是把这5个磁盘块当成新的可用空间,把原有的数据覆盖掉就可以了,例如:有时候把文件删除,通过数据恢复工具还能恢复回来,只要没有往里面存储新数据,就可以恢复回来;不想恢复可以使用文件粉碎机,比如360;所谓文件粉碎机在删除文件的时候,不是简单的把它标记为空闲,而是弄一大堆的随机数据把对应的磁盘块给它覆盖掉,比如填充一堆的0,再要找回来比较困难;

复制文件的过程:

复制一个文件无论多大速度都比较慢,说白了文件复制的过程就是创建新文件的过程,并填充为原来数据内容一样的过程,所以需要完全建立一个新文件,但是剪切非常快,因为剪贴的过程在同一个文件系统来说,它只是把目录对应的路径,这个目录项放到别的目录上去了,而你的inode还是那个inode,数据还是原来磁盘块的数据,根本就没动,但是必须要在同一个分区上才行,如果要跨分区就不可以了,跨分区这些对应指定的路径是不能跨分区引用的,所以跨分区剪切文件就意味着,过程是这样的,在新分区上建立一个新文件,把老分区的文件复制过去,在老分区上把文件删除;

文件系统:

现在分区越来越大了,在这个分区就算是建立了块位图,建立了inode位图,你会发现从块里面扫描一个空闲块速度仍然非常慢,哪怕在位图中扫,因为我有100W个块,从这100W个位图扫起来也没有那么快,事实上真的分区说起来比较复杂,它是整个分区建立完成以后,元数据区不是划分成一个inode区,一个块位图区什么之类的,而是先把我们的整个磁盘分区再划分为N个逻辑组,可以认为是分区下面的子分区,虽然对用户是不可见的,这样许许多多的子分区,这些子分区叫block group(块组),一个分区有多少块组事实上是不确定的,所以当前磁盘上有多少块组,必须有一个全局信息,说明以下当前磁盘分区一共有多少块组,分别是那些,而这个块可以理解为超级块,或者叫全局描述信息都行,而每一个快组内部它有这个块组一共有多少空闲块,每个快组中有块位图,inode位图等等;所以它又划分成一个子逻辑区域来管理的,当然管理概念和上面描述的是一样的;

文件类型里面除了文件目录之外还有几个特殊的文件类型

链接文件:

在Windows中所谓的链接就是快捷方式;可以通过多种不同的路径找到同一个文件,链接可以理解为找到同一文件的不同路径;

1、硬连接:每一个文件都有inode,而且inode有编号,如果说在整个文件上有多个目录的路径指向同一个inode,意味着;比如说在/backup/a/m.txt文件,同时在/backup/b/n.txt文件,而这两个文件指向同一个inode,这是没有问题的,所以通过m.txt和n.txt访问的是同一个文件,向这种直接指向同一个inode的不同路径它们彼此之间就可以称为叫硬链接

2、符号链接(软链接):每一个文件在磁盘上都有一个inode,比如说在/backup/a/下面有个m.txt,我们好不容易找到a的目录,在a目录找到了m.txt的inode号,于是找到了m.txt对应的条目,打开inode条目会发现,这个inode条目里面并没有存储任何数据,它也没有定义这个文件指向的磁盘块在什么地方,本来应该存储磁盘块的路径,它存的是另外一个文件/backup/b/n.txt的路径名,这就意味着还得从新来,找根、找backup、找b、找n.txt,而n.txt说我这里有对应的磁盘块,于是就找到文件了,不管怎么讲我们通过/backup/b/m.txt找到/backup/b/n.txt,就能找到文件,两个指向同一个inode和其中一个指向另外一个的路径是两种不同的方式,向后面这种方式,这个/backup/a/m.txt文件是多大,它本来应该指向磁盘块的,我统计这个文件有多大,把这些块加起来就是文件大小,但是它没有磁盘块,它里面存的是字符串,因此它有多大是字符个数;

符号链接(软链接)文件大小是被链接文件路径字符的个数;

符号链接所存储的权限对我们方式文件没有影响,我们去访问一个符号链接的时候,这个符号链接事实上指的是另外一个文件的路径,那意味着我们最终访问文件的权限取决于最终文件的权限,跟符号链接本身的权限没有关系;

符号链接权限和属主属组中间的数字叫硬链接的次数,本文件被硬链接的次数,不是符号链接,所以这个数字大于2的话,当我们去删除其中一个文件的时候这个文件不会被真正删除,只有硬链接的次数等于1的时候,再删除就彻底删除,而我们平常删除一个链接是删除不了的;

[root@Smoke ~]# ll /etc/(查看/etc目录下的文件及子目录,链接文件权限都是777的)
lrwxrwxrwx.  1(硬链接次数) root root      7 Apr 14 22:59 rc -> rc.d/rc(软链接文件大小是被链接文件字符个数)
lrwxrwxrwx.  1 root root     10 Apr 14 22:59 rc0.d -> rc.d/rc0.d
lrwxrwxrwx.  1 root root     10 Apr 14 22:59 rc1.d -> rc.d/rc1.d
lrwxrwxrwx.  1 root root     10 Apr 14 22:59 rc2.d -> rc.d/rc2.d
lrwxrwxrwx.  1 root root     10 Apr 14 22:59 rc3.d -> rc.d/rc3.d
lrwxrwxrwx.  1 root root     10 Apr 14 22:59 rc4.d -> rc.d/rc4.d
lrwxrwxrwx.  1 root root     10 Apr 14 22:59 rc5.d -> rc.d/rc5.d
lrwxrwxrwx.  1 root root     10 Apr 14 22:59 rc6.d -> rc.d/rc6.d

创建链接文件:

ln [-s -v] SRC DEST:不带选项默认创建硬链接,SRC是原文件,DEST是创建的链接文件,-s创建软链接,-v显示创建过程

硬链接:

  1、只能对文件创建,不能应用于目录;

  2、不能跨文件系统;

  3、创建硬链接会增加文件被链接的次数;

符号链接:

1、可应用于目录;

2、可以跨文件系统;

3、不会增加被链接文件的链接次数;

4、其大小为指定的路径所包含的字符个数;

du:显示文件系统或者目录它所占据整体空间大小,默认显示文件占据磁盘空间大小

-s: 显示目录及目录中的子文件,就是通过这个目录能够找到的所有文件它所占据的磁盘空间大小

-h: 单位换算

df: 显示磁盘分区使用情况,默认显示磁盘块使用情况

-h: 单位换算

-i: 查看inode使用情况

-P: 如果文件名过长,不换号显示

[root@Smoke backup]# cp /etc/rc.d/rc.sysinit ./abc(复制rc.sysinit到当前目录叫abc)[root@Smoke backup]# ll(查看当前目录下文件及子目录详细信息,abc文件的硬连接数为1)
total 24
-rwxr-xr-x  1 root root 19688 Jul  7 22:57 abc
-rw-rwxr--+ 1 root root   888 Jul  2 23:14 inittab
[root@Smoke backup]# mkdir test(创建目录test)
[root@Smoke backup]# ln abc test/abc2(给abc创建链接到叫abc2)
[root@Smoke backup]# ls -l(查看当前目录下文件及子目录详细信息,abc文件的硬连接数变为2)
total 28
-rwxr-xr-x  2 root root 19688 Jul  7 22:57 abc
-rw-rwxr--+ 1 root root   888 Jul  2 23:14 inittab
drwxr-xr-x  2 root root  4096 Jul  7 22:58 test
[root@Smoke backup]# cd test/(切换到test目录)
[root@Smoke test]# ll(查看当前目录文件及目录详细信息,test的硬连接数为2)
total 20
-rwxr-xr-x 2 root root 19688 Jul  7 22:57 abc2
[root@Smoke backup]# ls -i(查看文件的inode号,abc的inode号是261200)
261200 abc  261197 inittab  261202 test
[root@Smoke backup]# ls -i test/(查看test目录下的文件inode号,abc2的inode号也是261200)
261200 abc2
[root@Smoke backup]# rm abc(删除abc文件)
rm: remove regular file `abc'? y
[root@Smoke backup]# ls(查看当前目录文件及子目录,abc被删除)
inittab  test
[root@Smoke backup]# ls test/(查看test目录)
abc2
[root@Smoke backup]# cat test/abc2(查看abc2文件内容,可以访问)
[root@Smoke backup]# ls -i test/(查看abc2文件的inode号,没有发生变化,还是同一个文件)
261200 abc2
[root@Smoke backup]# ll -i test/(abc2文件的硬连接数变为1)
total 20
261200 -rwxr-xr-x 1 root root 19688 Jul  7 22:57 abc2
[root@Smoke backup]# mv test/abc2 abc(将abc2移动到当前目录并改名为abc)
[root@Smoke backup]# ls(查看当前目录下文件)
abc  inittab  test
[root@Smoke backup]# ln -sv /backup/abc /backup/test/abc2'(创建abc软链接abc2)
`/backup/test/abc2' -> `/backup/abc
[root@Smoke backup]# ls -i(查看当前目录文件的inode号,abc文件的inode号没有发送改变)
261200 abc  261197 inittab  261202 test
[root@Smoke backup]# ls -i test/(查看abc2文件的innode号,和abc的inode号不一样,说明不是同一文件)
261204 abc2
[root@Smoke backup]# ls -il test/(查看test目录下文件详细信息和inode号,abc文件大小为11,/backup/abc字符为11个)
total 0
261204 lrwxrwxrwx 1 root root 11 Jul  7 23:16 abc2 -> /backup/abc
[root@Smoke backup]# rm abc(删除abc文件)
rm: remove regular file `abc'? y
[root@Smoke backup]# ls -li test/(查看test目录下文件详细信息和inode号,abc2链接标记为红色,意思为损坏链接)
total 0
261204 lrwxrwxrwx 1 root root 11 Jul  7 23:16 abc2 -> /backup/abc
[root@Smoke backup]# cat /backup/test/abc2(访问abc2文件无法访问)
cat: /backup/test/abc2: No such file or directory
[root@Smoke backup]# cp /etc/inittab /backup/abc(拷贝/etc/inittab文件到/backup目录叫abc)
[root@Smoke backup]# ls -li test/(查看test目录下文件详细信息和inode号,abc2链接文件得到修复,并且inode号没有发生改变)
total 0
261204 lrwxrwxrwx 1 root root 11 Jul  7 23:16 abc2 -> /backup/abc
[root@Smoke backup]# mv abc def(改变abc文件名字叫def)
[root@Smoke backup]# ls -li test/(查看test目录下文件的详细信息和inode号,abc2链接文件被标记为红色,意思为损坏链接)
total 0
261204 lrwxrwxrwx 1 root root 11 Jul  7 23:16 abc2 -> /backup/abc
[root@Smoke backup]# cp /etc/issue abc(拷贝issue文件到当前目录叫abc)
[root@Smoke backup]# ls -li test/(查看test目录下文件详细信息和inode号,abc2链接文件被修复,它指的只是/backup/abc字符串,只要字符串文件存在就行,不管inode是多少)
total 0
261204 lrwxrwxrwx 1 root root 11 Jul  7 23:16 abc2 -> /backup/abc
[root@Smoke backup]# ls -l(查看当前目录详细信息,目录的硬连接数始终是2,因为它有.代表当前目录)
total 16
-rw-r--r--  1 root root   47 Jul  7 23:26 abc
-rw-r--r--  1 root root  884 Jul  7 23:22 def
-rw-rwxr--+ 1 root root  888 Jul  2 23:14 inittab
drwxr-xr-x  2 root root 4096 Jul  7 23:16 test
[root@Smoke backup]# ln test hello(无法给目录创建硬链接)
ln: `test': hard link not allowed for directory
[root@Smoke ~]# du /backup/(显示/backup目录每一个文件大小)
4        /backup/test
20        /backup/
[root@Smoke ~]# du -s /backup/(显示整个目录大小,-s查看整个目录)
20        /backup/
[root@Smoke ~]# du -sh /backup/(显示整个目录大小,并做单位换算)
20K        /backup/
[root@Smoke ~]# df(查看磁盘分区使用情况)
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda2       20158332 6166544  12967788  33% /
tmpfs             506172       0    506172   0% /dev/shm
/dev/sda1         198337   53934    134163  29% /boot
[root@Smoke ~]# df -h(查看磁盘分区使用情况,-h并做单位换算)
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        20G  5.9G   13G  33% /
tmpfs           495M     0  495M   0% /dev/shm
/dev/sda1       194M   53M  132M  29% /boot
[root@Smoke ~]# df -i(查看磁盘分区使用情况,-i查看有多少inode可以用)
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/sda2      1281120 142822 1138298   12% /
tmpfs           126543      1  126542    1% /dev/shm
/dev/sda1        51200     44   51156    1% /boot
[root@Smoke ~]# df -P -i(查看磁盘分区使用情况,-P不换行显示,-i显示inode使用情况)
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/sda2      1281120 142822 1138298   12% /
tmpfs           126543      1  126542    1% /dev/shm
/dev/sda1        51200     44   51156    1% /boot

链接文件:

硬链接

符号连接(软连接)

设备文件:

  b块设备: 按块为单位,随机访问的设备;

  c字符设备:按字符为单位,线性设备;

  b块设备: 硬盘

  c字符设备: 键盘

/dev

  主设备号 (major number)

    标识设备类型

  次设备号 (minor number)

    标识同一种类型中不同设备

系统主要以主设备号和次设备号引用设备文件

设备文件没有大小,并不占用磁盘空间,它的主设备号和次设备号也是存储在inode当中,在inode标号段类似与链接文件,链接文件存储的是另一个文件的路径,设备文件存储的是主设备号和次设备号,所以它们没有大小,大小指的是真正占用存储数据的磁盘块的大小

mknod:创建字符或块设备的特殊文件

mknod [OPTION]... NAME TYPE [MAJOR MINOR]:OPTION选项,NAME路径及文件名称,TYPE字符设备还是块设备,MAJOR主设备号,MINOR次设备号,主次设备号可以省略,可以根据文件名来判定到底属于那种类型

  -m MODE:指定文件权限

  b: 块设备文件

  c: 字符设备文件

  p:管道文件

设备文件的主要目的是作为设备的访问入口,因此必须要确保主设备号一定是跟某类设备关联起来的,设备号默认是被内核识别的,所以当前系统一旦插入某个硬件上来,这个硬件它的设备号被内核识别为某个主设备号,那么我们通过这个设备文件访问的数据内容,或者往这个文件里面发的数据都自动被发往那个设备上去;

注意:不要随意向某个设备文件使用echo "hello" >> /dev/sda发送文件过去,如果设备是硬盘会将这段字符写入到硬盘最开始那段空间,将会覆盖掉MBR中的内容,导致系统无法启动,向终端发送还是没问题的

硬盘设备的设备文件名:

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: 第一个逻辑分区

查看当前系统识别了几块硬盘:

fdisk -l [/dev/to/some_device_file]:查看当前系统当前所有磁盘及磁盘分区

Linux支持的文件系统:

FAT32:vfat,windows文件系统

NTFS:windows文件系统

ISO9660:光盘数据存储格式

CIFS:通用互联网文件系统

ext2:

ext3:

ext4

xfs:

reiserfs:

jfs:日志文件系统

nfs:linux网络文件系统

ocfs2:集群文件系统

gfs2:

swap:交换内存

文件系统本身是一个让我们在磁盘上创建文件管理的一种软件,因此文件系统本身跟某个特定的软件没有关系,它是内核中的功能,任何进程访问文件的时候,文件首先都得被识别,所以文件系统本身是内核中的功能,但是要把某个设备格式化成某个类型的文件系统,管理文件系统的程序在用户空间里面,是一个用户进程,用户进程可以实现将某个硬盘设备的分区给它格式化为内核支持的某种类型的文件系统,

格式化:

低级格式化:创建磁道

高级格式:创建文件系统,mkfs -t txt3

VFS:Virtual FileSystem,虚拟文件系统,可以弥合不同文件系统

对linux而言一个分区就是一个独立的文件系统,因此每个分区都可以单独格式化,而且每个分区可以创建不同类型的文件系统,但最终都要归并到根下,而这种归并到根下的方式叫做挂载或关联的方式

根所在的分区叫做根文件系统,根文件系统至关重要,在根下面不是每一个目录都可以独立出去;

低级格式化是厂家完成的,高级格式化就是为了创建文件系统,文件也只有创建完文件系统以后才能被挂载,被关联到根下的某个目录作为你访问入口

管理磁盘分区:

fdisk /dev/sda

  p: 显示当前硬件的分区,包括没保存的改动

  n: 创建新分区

    e: 扩展分区

    p: 主分区

  d: 删除一个分区

  w: 保存退出

  q: 不保存退出

  t: 修改分区类型

    L: 显示支持的文件系统类型

  l: 显示所支持的所有类型

扩展分区不能直接使用,扩展分区只是一个指针,它是指向另外一个分区表的指针而已,所以在另外一个地方还要新建分区

新建完的分区内核立即识别,所以也无法格式化,可以让内核重读分区表或者重启操作系统

cat /proc/partitions:查看内核识别的分区

partprobe:让内核重读分区表

partx -a /dev/sda:REDHAT 6.X版本让内核重新加载sda设备命令,-a添加指定分区或磁盘读取并添加所有分区

[root@Smoke ~]# ll /dev/(查看/dev目录文件详细信息)
crw--w---- 1 root tty       4(主设备号),  10(次设备号) Jul  3 00:31 tty10
crw--w---- 1 root tty       4,  11 Jul  3 00:31 tty11
crw--w---- 1 root tty       4,  12 Jul  3 00:31 tty12
crw--w---- 1 root tty       4,  13 Jul  3 00:31 tty13
crw--w---- 1 root tty       4,  14 Jul  3 00:31 tty14
crw--w---- 1 root tty       4,  15 Jul  3 00:31 tty15
crw--w---- 1 root tty       4,  16 Jul  3 00:31 tty16
crw--w---- 1 root tty       4,  17 Jul  3 00:31 tty17
crw--w---- 1 root tty       4,  18 Jul  3 00:31 tty18
[root@Smoke ~]# mknod mydev c 66 0(创建字符设备mydev主设备号66次设备号0)
[root@Smoke ~]# ls -l(查看当前目录下文件详细信息,默认权限644)
crw-r--r--   1 root root     66, 0 Jul  8 22:30 mydev
[root@Smoke ~]# mknod -m 640 mydev2 c 66 1(创建字符设备mydev2,权限为640,主设备号66次设备号1)
crw-r--r--   1 root root     66, 0 Jul  8 22:30 mydev
crw-r-----   1 root root     66, 1 Jul  8 22:32 mydev2
[root@Smoke ~]# tty(查看当前的tty终端)
/dev/pts/0
[root@Smoke ~]# tty(查看当前的tty终端)
/dev/pts/1
[root@Smoke ~]# echo "hello" >> /dev/pts/1(显示hello字符串输出追加到/dev/pts/1终端)
[root@Smoke ~]# hello(在/dev/pts/1终端收到/dev/pts/0终端发送的字符)
[root@Smoke ~]# fdisk -l(查看当前系统所有磁盘及分区)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
[root@Smoke ~]# fdisk -l /dev/sda(查看sda磁盘设备及分区)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
[root@Smoke ~]# fdisk -l /dev/sda
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
[root@Smoke ~]# fdisk /dev/sda(管理磁盘分区,进入交互式)
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
        switch off the mode (command 'c') and change display units to
        sectors (command 'u').
Command (m for help): m(获取命令帮助)
Command action
  a   toggle a bootable flag
  b   edit bsd disklabel
  c   toggle the dos compatibility flag
  d   delete a partition
  l   list known partition types
  m   print this menu
  n   add a new partition
  o   create a new empty DOS partition table
  p   print the partition table
  q   quit without saving changes
  s   create a new empty Sun disklabel
  t   change a partition's system id
  u   change display/entry units
  v   verify the partition table
  w   write table to disk and exit
  x   extra functionality (experts only)
Command (m for help): p(显示当前磁盘的分区)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
Command (m for help): n(创建新的分区)
Command action
  e   extended
  p   primary partition (1-4)
p(主分区)
Selected partition 4(选择分区编号,总共有4个主分区,编号为1-4,如果前面的编号都被使用,自动选择4)
First cylinder (2706-5221, default 2706): (选择其实柱面从多少开始默认)
Using default value 2706
Last cylinder, +cylinders or +size{K,M,G} (2706-5221, default 5221): +10G(可以写结束柱面号或者大小)
Command (m for help): p(查看创建的分区)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
/dev/sda4            2706        4011    10483957+  83  Linux
Command (m for help): n(再创建新分区无法创建,因为最多4个主分区)
You must delete some partition and add an extended partition first
Command (m for help): d(删除分区)
Partition number (1-4): 4(删除编号为4的分区)
Command (m for help): p(查看分区情况)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
Command (m for help): n(创建新的分区)
Command action
  e   extended
  p   primary partition (1-4)
e(扩展分区)
Selected partition 4(编号4)
First cylinder (2706-5221, default 2706): (起始磁盘柱面)
Using default value 2706
Last cylinder, +cylinders or +size{K,M,G} (2706-5221, default 5221): (结束磁盘柱面,全部给扩展分区)
Using default value 5221
Command (m for help): p(查看分区情况)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
/dev/sda4            2706        5221    20203282+   5  Extended
Command (m for help): n(新建分区)
First cylinder (2706-5221, default 2706): (起始柱面)
Using default value 2706
Last cylinder, +cylinders or +size{K,M,G} (2706-5221, default 5221): +10G(创建10G分区)
Command (m for help): p(查看分区情况)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
/dev/sda4            2706        5221    20203282+   5  Extended
/dev/sda5            2706        4011    10483926   83  Linux    
Command (m for help): t(修改分区类型)
Partition number (1-5): 5(分区编号)
Hex code (type L to list codes): L(显示支持的文件系统类型)
0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris        
1  FAT12           39  Plan 9          82  Linux swap / So c1  DRDOS/sec (FAT-
2  XENIX root      3c  PartitionMagic  83  Linux           c4  DRDOS/sec (FAT-
3  XENIX usr       40  Venix 80286     84  OS/2 hidden C:  c6  DRDOS/sec (FAT-
4  FAT16 <32M      41  PPC PReP Boot   85  Linux extended  c7  Syrinx        
5  Extended        42  SFS             86  NTFS volume set da  Non-FS data    
6  FAT16           4d  QNX4.x          87  NTFS volume set db  CP/M / CTOS / .
7  HPFS/NTFS       4e  QNX4.x 2nd part 88  Linux plaintext de  Dell Utility  
8  AIX             4f  QNX4.x 3rd part 8e  Linux LVM       df  BootIt        
9  AIX bootable    50  OnTrack DM      93  Amoeba          e1  DOS access    
a  OS/2 Boot Manag 51  OnTrack DM6 Aux 94  Amoeba BBT      e3  DOS R/O        
b  W95 FAT32       52  CP/M            9f  BSD/OS          e4  SpeedStor      
c  W95 FAT32 (LBA) 53  OnTrack DM6 Aux a0  IBM Thinkpad hi eb  BeOS fs        
e  W95 FAT16 (LBA) 54  OnTrackDM6      a5  FreeBSD         ee  GPT            
f  W95 Ext'd (LBA) 55  EZ-Drive        a6  OpenBSD         ef  EFI (FAT-12/16/
10  OPUS            56  Golden Bow      a7  NeXTSTEP        f0  Linux/PA-RISC b
11  Hidden FAT12    5c  Priam Edisk     a8  Darwin UFS      f1  SpeedStor      
12  Compaq diagnost 61  SpeedStor       a9  NetBSD          f4  SpeedStor      
14  Hidden FAT16 <3 63  GNU HURD or Sys ab  Darwin boot     f2  DOS secondary  
16  Hidden FAT16    64  Novell Netware  af  HFS / HFS+      fb  VMware VMFS    
17  Hidden HPFS/NTF 65  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE
18  AST SmartSleep  70  DiskSecure Mult b8  BSDI swap       fd  Linux raid auto
1b  Hidden W95 FAT3 75  PC/IX           bb  Boot Wizard hid fe  LANstep        
1c  Hidden W95 FAT3 80  Old Minix       be  Solaris boot    ff  BBT            
1e  Hidden W95 FAT1  
Hex code (type L to list codes): 82(更改分区类型为Linux swap)
Changed system type of partition 5 to 82 (Linux swap / Solaris)
Command (m for help): p(查看分区情况)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
/dev/sda4            2706        5221    20203282+   5  Extended
/dev/sda5            2706        4011    10483926   82  Linux swap / Solaris
Command (m for help): n(创建分区)
First cylinder (4012-5221, default 4012): (起始柱面)
Using default value 4012
Last cylinder, +cylinders or +size{K,M,G} (4012-5221, default 5221): +8G(创建8G分区)
Command (m for help): p(查看分区情况)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
/dev/sda4            2706        5221    20203282+   5  Extended
/dev/sda5            2706        4011    10483926   82  Linux swap / Solaris
/dev/sda6            4012        5056     8393931   83  Linux
Command (m for help): w(保存退出)
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
[root@Smoke ~]# fdisk -l(查看系统所有磁盘及分区)
Disk /dev/sda: 42.9 GB, 42949672960 bytes
255 heads, 63 sectors/track, 5221 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031216
  Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          26      204800   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              26        2576    20480000   83  Linux
/dev/sda3            2576        2706     1048576   82  Linux swap / Solaris
/dev/sda4            2706        5221    20203282+   5  Extended
/dev/sda5            2706        4011    10483926   82  Linux swap / Solaris
/dev/sda6            4012        5056     8393931   83  Linux
[root@Smoke ~]# cat /proc/partitions(显示内核中识别那些分区)
major minor  #blocks  name
  8        0   41943040 sda
  8        1     204800 sda1
  8        2   20480000 sda2
  8        3    1048576 sda3
[root@Smoke ~]# partprobe(让内核重读内核分区表)
[root@Smoke ~]# cat /proc/partitions(显示内核中识别的分区)
major minor  #blocks  name
  8        0   41943040 sda
  8        1     204800 sda1
  8        2   20480000 sda2
  8        3    1048576 sda3
  8        4          1 sda4
  8        5   10483926 sda5
  8        6    8393931 sda6