26、脚本编程之while语句,read,echo命令

26.1 脚本编程结构简介

顺序结构

选择结构

if

case

循环结构

for

while

until

26.2 while循环

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

26.3 用户交互(read)

read 读取用户输入(可一次读取多个输入分给不同的用户)

-p 显示提示

-t 指定超时时间

[root@localhost ~]# read a b c

how ae^H you

[root@localhost ~]# echo $a

how

[root@localhost ~]# echo $b

ae

[root@localhost ~]# echo $c

you

[root@localhost ~]# read a b c

how are

[root@localhost ~]# echo $a

how

[root@localhost ~]# echo $c

[root@localhost ~]# read a b c

how lo^H are you

[root@localhost ~]# read $a

abcd

[root@localhost ~]# read a b c

how old are you

[root@localhost ~]# echo $a

how

[root@localhost ~]# echo $c

are you

[root@localhost ~]# 

[root@localhost ~]# read -p “please enter your name:” -t 5 name

please enter your name:[root@localhost ~]# read -p “please enter your name:” -t 5 name

please enter your name:bob

[root@localhost ~]# echo $name

bob

[root@localhost ~]# 

26.4 bash脚本调试

bash

-n scripts.sh 检测脚本是否有错误

-x scripts.sh 分步执行脚本

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

[root@Daniel-R480 ~]# ./translate.sh 

Input something:ech

ECH

Input something:quit

[root@Daniel-R480 ~]# 

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

写一个脚本:

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

d|D) show disk usages.

m|M) show memory usages.

s|S) show swap usages.

*) quit.

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

[root@Daniel-R480 ~]# ./showdisk.sh 

d|D) show disk usages.

m|M)show memory usages.

s|S)show swap usages.

*)quit

Your choice:s

Swap usage:

Swap:         30291           0       30291

[root@Daniel-R480 ~]# ./showdisk.sh 

d|D) show disk usages.

m|M)show memory usages.

s|S)show swap usages.

*)quit

Your choice:q

Unknown..

[root@Daniel-R480 ~]# echo $?

9

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

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..”

        exit 9;;

esac

扩展:

当用户选择完成,显示相应信息后,不退出;而让用户再一次选择,再次显示相应内容;除了用户使用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..”

        exit 9;;

esac

read -p “Your choice:” CHOICE

echo输出不同格式的文本

[root@Daniel-R480 ~]# echo -e “\033[1mHello\033[0m,world.”

Hello,world.

[root@Daniel-R480 ~]# echo -e “\033[31mHello\033[0m,world.”

Hello,world.

[root@Daniel-R480 ~]# echo -e “\033[32mHello\033[0m,world.”

Hello,world.

[root@Daniel-R480 ~]# echo -e “\033[41mHello\033[0m,world.”

Hello,world.

[root@Daniel-R480 ~]# echo -e “\033[42mHello\033[0m,world.”

Hello,world.

[root@Daniel-R480 ~]# echo -e “\033[1,31,43mHello\033[0m,world.”

Hello,world.

[root@Daniel-R480 ~]# echo -e “\033[1;31;43mHello\033[0m,world.”

Hello,world.

[root@Daniel-R480 ~]#

25、压缩、解压缩及归档工具

25.1 早期的压缩命令

    compress: FILENAME.Z

    uncompress

25.2 目前常用的压缩命令

压缩格式:gz, bz2, xz, zip, Z

压缩算法:算法不同,压缩比也会不同;

1、gzip: .gz

    gzip /PATH/TO/SOMEFILE:压缩完成后会删除原文件

-d:解压缩

-c:将结果输出至标准输出

-#:1-9,指定压缩比,默认是6;

gunzip: 解压缩

gunzip /PATH/TO/SOMEFILE.gz: 解压完成后会删除原文件

查看压缩文件内容

zcat /PATH/TO/SOMEFILE.gz: 不解压的情况,查看文本文件的内容

3、bzip2: .bz2

比gzip有着更大压缩比的压缩工具,使用格式近似

bzip2 /PATH/TO/SOMEFILE

-d:解压缩

-#: 1-9,默认是6

-k: 压缩时保留原文件

bunzip2 /PATH/TO/SOMEFILE.bz2

解压缩命令

bzcat:不解压查看压缩文件内容

4、xz: .xz

xz /PATH/TO/SOMEFILE

-d:解压缩

-#: 1-9, 默认是6

-k: 压缩时保留原文件

unxz:解压缩

xzdec:体积很小的解压缩xz文件的软件

xzcat :不解压的情况,查看文本文件的内容

5、zip

zip: 既归档又压缩的工具,可以压缩目录

zip FILENAME.zip FILE1 FILE2 …: 压缩后不删除原文件

unzip FILENAME.zip

使用deflat的压缩算法

archive: 归档,归档本身并不意味着压缩

分卷打包

zip -s 50m -r test.zip /etc   #(把etc目录按50M大小分卷打包。)

-s: 创建分卷的大小

-r: 循环压缩文件夹下面的内容

zip -s 0 test.zip  –out etc.zip  #把test.zip分卷合并成etc.zip压缩包

6、tar

tar: 归档工具,只归档不压缩, .tar

-c: 创建归档文件

-f FILE.tar: 操作的归档文件

-x: 展开归档

–xattrs: 归档时,保留文件的扩展属性信息

-t: 不展开归档,直接查看归档了哪些文件

-zcf: 归档并调用gzip压缩

-zxf: 调用gzip解压缩并展开归档,-z选项可省略

-jcf: 归档并调用bzip2压缩

-jxf:调用bzip2解压缩并展开归档,-j选项可省略

-Jcf: 归档并调用 xz压缩

-Jxf:调用xz解压缩并展开归档,-J选项可省略

7、ccpio

cpio: 比tar更古老的归档工具

练习:写一个脚本

从键盘让用户输入几个文件,脚本能够将此几个文件归档压缩成一个文件;

read:

    -p “PROMPT”: 给出提示

[root@localhost ~]# vim tar.sh 

[root@localhost ~]# bash -n tar.sh 

[root@localhost ~]# ./tar.sh 

Please input three file:a b c

Destination:tar

Compress type:(gzip,bzip2,xz)xz

[root@localhost ~]# ll

total 20

-rw——-. 2 root root 1426 May 27 06:31 a

-rw——-. 2 root root 1426 May 27 06:31 anaconda-ks.cfg

lrwxrwxrwx. 1 root root   15 Jul 21 21:46 b -> anaconda-ks.cfg

-rw-r–r–. 1 root root    0 Jul 23 03:56 c

-rwxr-xr-x. 1 root root  378 Jul 23 04:09 tar.sh

-rw-r–r–. 1 root root 1072 Jul 23 04:09 tar.tar.xz

-rw-r–r–. 1 root root   32 Jul 23 03:12 test.xz

[root@localhost ~]# tar -tf tar.tar.xz 

a

b

c

#脚本

#!/bin/bash

#

read -p “Please input three file:” FILE1 FILE2 FILE3

read -p “Destination:” DEST

read -p “Compress type:(gzip,bzip2,xz)” TYPE

case $TYPE in

gzip)

        tar -zcf ${DEST}.tar.gz $FILE1 $FILE2 $FILE3;;

bzip2)

        tar -jcf ${DEST}.tar.bz2 $FILE1 $FILE2 $FILE3;;

xz)

        tar -cf ${DEST}.tar $FILE1 $FILE2 $FILE3

        xz ${DEST}.tar;;

$)

        echo “wrong Input,exiting”

        exit 9;;

esac

24、Linux文件系统及分区挂载

24.1 Linux支持的文件系统

1、文件操作:

    打开,关闭,创建,删除,修改

2、文件系统类型(Linux几乎全部支持)

FAT32,NTFS,ISO9660,CIFS,ext2(CentOS5),ext3(CentOS5,6),ext4(CentOS6,7),xfs(CentOS7),btrfs(CentOS7),reiserfs,jfs,nfs,ocfs2,gfs2

swap:交换分区(可以将硬盘当做内存用的部分,将一些不常用的进程放于swap当中)

数据库:swap可以分配小一点(512M,1G左右)

hadoop:swap可以分配大一点(8G甚至以上,太大影响系统速度)

光盘:iso9660

Windows:fat32,NTFS

UNIX:FFS,UFS,JFS2

网络文件系统:NFS,CIFS

集群文件系统:GFS2,OCFS2

分布式文件系统:ceph

moosefs,mogilefs,GlusterFS,Lustre

根据其是否支持“journal”功能:

日志文件系统(有日志区域):ext3,ext4,xfs,…

非日志型文件系统(无日志区域):ext2,vfat

3、文件系统的组成部分:

内核中的模块:ext4,xfs,vfat

用户空间的管理工具:mkfs.ext2,mkfs.ext4,mkfs.vffat(FAT32)

4、Linux VFS:Virtual File System(虚拟文件系统):

用来统一各种文件系统,为开发者提供一个标准的文件接口,所以Linux支持众多的文件系统

查看linux支持的文件系统:

[root@localhost ~]# cat /proc/filesystems 

nodev   sysfs

nodev   rootfs

nodev   ramfs

nodev   bdev

nodev   proc

nodev   cgroup

nodev   cpuset

nodev   tmpfs

nodev   devtmpfs

nodev   debugfs

nodev   securityfs

nodev   sockfs

nodev   pipefs

nodev   anon_inodefs

nodev   configfs

nodev   devpts

nodev   hugetlbfs

nodev   autofs

nodev   pstore

nodev   mqueue

nodev   selinuxfs

    xfs

[root@localhost ~]# 

查看内核支持的模块(CentOS 7)

[root@localhost ~]# lsmod

Module                  Size  Used by

ip6t_rpfilter          12595  1 

ipt_REJECT             12541  2 

nf_reject_ipv4         13373  1 ipt_REJECT

ip6t_REJECT            12625  2 

nf_reject_ipv6         13717  1 ip6t_REJECT

xt_conntrack           12760  17 

ip_set                 36439  0 

nfnetlink              14696  1 ip_set

ebtable_nat            12807  1 

ebtable_broute         12731  1 

bridge                136173  1 ebtable_broute

stp                    12976  1 bridge

llc                    14552  2 stp,bridge

ip6table_nat           12864  1 

nf_conntrack_ipv6      18935  10 

nf_defrag_ipv6         35104  1 nf_conntrack_ipv6

nf_nat_ipv6            14131  1 ip6table_nat

ip6table_mangle        12700  1 

ip6table_security      12710  1 

ip6table_raw           12683  1 

iptable_nat            12875  1 

nf_conntrack_ipv4      15053  9 

nf_defrag_ipv4         12729  1 nf_conntrack_ipv4

nf_nat_ipv4            14115  1 iptable_nat

nf_nat                 26787  2 nf_nat_ipv4,nf_nat_ipv6

nf_conntrack          133387  6 nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_conntrack_ipv4,nf_conntrack_ipv6

iptable_mangle         12695  1 

iptable_security       12705  1 

iptable_raw            12678  1 

ebtable_filter         12827  1 

ebtables               35009  3 ebtable_broute,ebtable_nat,ebtable_filter

ip6table_filter        12815  1 

ip6_tables             26901  5 ip6table_filter,ip6table_mangle,ip6table_security,ip6table_nat,ip6table_raw

iptable_filter         12810  1 

vmw_vsock_vmci_transport    30577  1 

vsock                  35327  2 vmw_vsock_vmci_transport

iosf_mbi               13523  0 

crc32_pclmul           13113  0 

ghash_clmulni_intel    13259  0 

aesni_intel            69884  0 

lrw                    13286  1 aesni_intel

gf128mul               14951  1 lrw

glue_helper            13990  1 aesni_intel

ablk_helper            13597  1 aesni_intel

cryptd                 20359  3 ghash_clmulni_intel,aesni_intel,ablk_helper

ppdev                  17671  0 

btusb                  41436  0 

btrtl                  12945  1 btusb

btbcm                  14040  1 btusb

btintel                15709  1 btusb

bluetooth             544565  5 btbcm,btrtl,btusb,btintel

vmw_balloon            18190  0 

joydev                 17377  0 

rfkill                 22391  1 bluetooth

sg                     40721  0 

pcspkr                 12718  0 

ahci                   34042  0 

libahci                31992  1 ahci

nfit                   49183  0 

nvme                   27722  0 

nvme_core              52964  1 nvme

libnvdimm             132047  1 nfit

parport_pc             28165  0 

parport                42299  2 ppdev,parport_pc

shpchp                 37032  0 

i2c_piix4              22390  0 

vmw_vmci               67013  1 vmw_vsock_vmci_transport

ip_tables              27115  5 iptable_security,iptable_filter,iptable_mangle,iptable_nat,iptable_raw

xfs                   978100  3 

libcrc32c              12644  3 xfs,nf_nat,nf_conntrack

sd_mod                 46322  3 

crc_t10dif             12714  1 sd_mod

sr_mod                 22416  0 

cdrom                  42556  1 sr_mod

crct10dif_generic      12647  0 

ata_generic            12910  0 

pata_acpi              13038  0 

vmwgfx                235405  1 

drm_kms_helper        159169  1 vmwgfx

syscopyarea            12529  1 drm_kms_helper

sysfillrect            12701  1 drm_kms_helper

sysimgblt              12640  1 drm_kms_helper

fb_sys_fops            12703  1 drm_kms_helper

ttm                    99345  1 vmwgfx

drm                   370825  4 ttm,drm_kms_helper,vmwgfx

crct10dif_pclmul       14289  1 

crct10dif_common       12595  3 crct10dif_pclmul,crct10dif_generic,crc_t10dif

crc32c_intel           22079  1 

mptspi                 22542  2 

serio_raw              13413  0 

i2c_core               40756  3 drm,i2c_piix4,drm_kms_helper

e1000                 137500  0 

ata_piix               35038  0 

scsi_transport_spi     30732  1 mptspi

libata                238896  5 ahci,pata_acpi,libahci,ata_generic,ata_piix

mptscsih               40150  1 mptspi

mptbase               105960  2 mptspi,mptscsih

dm_mirror              22124  0 

dm_region_hash         20813  1 dm_mirror

dm_log                 18411  2 dm_region_hash,dm_mirror

dm_mod                123303  11 dm_log,dm_mirror

[root@localhost ~]# 

Linux每个分区就可以使用一个独立的文件系统,但最后都要被挂载在根目录下

CPU分为四个环

    最内部的环ring0跑内核,最外部的环ring3跑软件,ring1,ring2不在使用

所以只有内核可以进行硬件调用,软件必须通过内核才能实现硬件的调用

24.2 磁盘管理

1、文件系统管理

创建文件系统:重新创建文件系统会损坏原有文件

mkfs: make file system

(1)-t FSTYPE 

mkfs -t ext2 = mkfs.ext2

mkfs -t ext3 = mkfs.ext3 = mke2fs -j = mke2fs -t ext3

(2)mkfs.FS_TYPE /dev/DEVICE (FS_TYPE指的是文件系统类型)

mke2fs:专门管理ext系列文件系统:

-t {ext2|ext3|ext4}:指定格式

-j: 创建ext3类型文件系统(相当于-t ext3)

-b BLOCK_SIZE: 指定块大小,默认为4096;可用取值为1024、2048或4096;

-L LABEL:指定分区卷标;

-m #: 指定预留给超级用户的块数百分比(为管理人员预备的)

-i #: 用于指定为多少字节的空间创建一个inode,默认为8192;此大小不应小于block大小;

-N #: 指定inode个数;

-F: 强制创建文件系统;

-E: 用户指定额外文件系统属性; 

-O FEATURE[,…]:启用指定特性

-O ^FEATURE:关闭指定特性

[root@localhost ~]# mke2fs -b 1024 -m 3 -L MYDATA /dev/sdc

mke2fs 1.42.9 (28-Dec-2013)

/dev/sdc is entire device, not just one partition!

Proceed anyway? (y,n) y

Filesystem label=MYDATA

OS type: Linux

Block size=1024 (log=0)

Fragment size=1024 (log=0)

Stride=0 blocks, Stripe width=0 blocks

65536 inodes, 1048576 blocks

31457 blocks (3.00%) reserved for the super user

First data block=1

Maximum filesystem blocks=68157440

128 block groups

8192 blocks per group, 8192 fragments per group

512 inodes per group

Superblock backups stored on blocks: 

    8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553, 

    1024001

Allocating group tables: done                            

Writing inode tables: done                            

Writing superblocks and filesystem accounting information: done   

[root@localhost ~]# blkid /dev/sdc

/dev/sdc: LABEL=”MYDATA” UUID=”a59eac3b-c56d-40a9-b433-972cdb48afa6″ TYPE=”ext2″ 

[root@localhost ~]# 

blkid: 查询或查看磁盘设备的相关属性

-U UUID:根据指定的UUID来查找对应的设备

-L  LABEL:根据制定的LABEL来查找对应的设备

    [root@localhost ~]# blkid

    /dev/sda1: UUID=”c3a88fcb-06d4-4775-9a27-971904c2b154″ TYPE=”xfs” 

    /dev/sda2: UUID=”0R0BFP-witm-SfMZ-d9an-26rT-JDtg-XzwGqy” TYPE=”LVM2_member” 

    /dev/mapper/centos-root: UUID=”71c7bb53-2826-49e8-bb0c-d6a112a01836″ TYPE=”xfs” 

    /dev/mapper/centos-swap: UUID=”eb2dd31d-36f2-47e7-a474-7025f2dd6a1b” TYPE=”swap” 

    /dev/mapper/centos-home: UUID=”92db6af3-9a84-4284-9a59-d4e9f79cb7ab” TYPE=”xfs

[root@localhost ~]# mkfs.ext4 /dev/sdc

mke2fs 1.42.9 (28-Dec-2013)

/dev/sdc is entire device, not just one partition!

Proceed anyway? (y,n) y

Filesystem label=

OS type: Linux

Block size=4096 (log=2)

Fragment size=4096 (log=2)

Stride=0 blocks, Stripe width=0 blocks

65536 inodes, 262144 blocks

13107 blocks (5.00%) reserved for the super user

First data block=0

Maximum filesystem blocks=268435456

8 block groups

32768 blocks per group, 32768 fragments per group

8192 inodes per group

Superblock backups stored on blocks: 

    32768, 98304, 163840, 229376

Allocating group tables: done                            

Writing inode tables: done                            

Creating journal (8192 blocks): done

Writing superblocks and filesystem accounting information: done

[root@localhost ~]# blkid /dev/sdc

/dev/sdc: UUID=”ae7e23e0-db47-4b53-bb5d-fda50773ab8c” TYPE=”ext4″ 

[root@localhost ~]# 

[root@localhost ~]# mkfs.ext4 /dev/sdc

mke2fs 1.42.9 (28-Dec-2013)

/dev/sdc is entire device, not just one partition!

Proceed anyway? (y,n) y

Filesystem label=

OS type: Linux

Block size=4096 (log=2)

Fragment size=4096 (log=2)

Stride=0 blocks, Stripe width=0 blocks

65536 inodes, 262144 blocks

13107 blocks (5.00%) reserved for the super user

First data block=0

Maximum filesystem blocks=268435456

8 block groups

32768 blocks per group, 32768 fragments per group

8192 inodes per group

Superblock backups stored on blocks: 

    32768, 98304, 163840, 229376

Allocating group tables: done                            

Writing inode tables: done                            

Creating journal (8192 blocks): done

Writing superblocks and filesystem accounting information: done

[root@localhost ~]# blkid /dev/sdc

/dev/sdc: UUID=”ae7e23e0-db47-4b53-bb5d-fda50773ab8c” TYPE=”ext4″ 

[root@localhost ~]# 

[root@localhost ~]# mkfs.xfs -L MYDATA /dev/sdc

mkfs.xfs: /dev/sdc appears to contain an existing filesystem (ext4).

mkfs.xfs: Use the -f option to force overwrite.

[root@localhost ~]# mkfs.xfs -f /dev/sdc

meta-data=/dev/sdc               isize=512    agcount=4, agsize=65536 blks

         =                       sectsz=512   attr=2, projid32bit=1

         =                       crc=1        finobt=0, sparse=0

data     =                       bsize=4096   blocks=262144, imaxpct=25

         =                       sunit=0      swidth=0 blks

naming   =version 2              bsize=4096   ascii-ci=0 ftype=1

log      =internal log           bsize=4096   blocks=2560, version=2

         =                       sectsz=512   sunit=0 blks, lazy-count=1

realtime =none                   extsz=4096   blocks=0, rtextents=0

[root@localhost ~]# blkid /dev/sdc

/dev/sdc: UUID=”dd14e08c-1757-4cc5-986c-53de7ec05f13″ TYPE=”xfs” 

[root@localhost ~]# mkfs.btrfs -f /dev/sdc

btrfs-progs v4.9.1

See http://btrfs.wiki.kernel.org for more information.

Label:              (null)

UUID:               9671cf06-920b-4738-9bba-81a3b00fc2db

Node size:          16384

Sector size:        4096

Filesystem size:    1.00GiB

Block groups:

  Data:             single            8.00MiB

  Metadata:         DUP              51.19MiB

  System:           DUP               8.00MiB

SSD detected:       no

Incompat features:  extref, skinny-metadata

Number of devices:  1

Devices:

   ID        SIZE  PATH

    1     1.00GiB  /dev/sdc

[root@localhost ~]# blkid /dev/sdc

/dev/sdc: UUID=”9671cf06-920b-4738-9bba-81a3b00fc2db” UUID_SUB=”20223c43-c91d-4a50-9297-66e3433f6e11″ TYPE=”btrfs” 

[root@localhost ~]# 

2、其他常用工具

(1)e2label DEVICE [LABEL]

用于查看或定义EXT文件系统的卷标

[root@localhost ~]# e2label /dev/sdc

MYDATA

[root@localhost ~]# e2label /dev/sdc DATA

[root@localhost ~]# e2label /dev/sdc

DATA

[root@localhost ~]# 

(2)tune2fs: 调整文件系统的相关可调整属性的值

-l:查看指定文件系统超级块信息;super block

-j: 不损害原有数据,将ext2升级为ext3;

-L LABEL: 设定或修改卷标; 

-m #: 调整预留百分比;

-r #: 指定预留块数;

-O:文件系统属性启用或禁用

-o: 设定默认挂载选项;

        acl

-c #:指定挂载次数达到#次之后进行自检,0或-1表关闭此功能;

-i #: 每挂载使用多少天后进行自检;0或-1表示关闭此功能;

-l: 显示超级块中的信息;

[root@localhost ~]# tune2fs -l /dev/sdc

tune2fs 1.42.9 (28-Dec-2013)

Filesystem volume name:   DATA

Last mounted on:          <not available>

Filesystem UUID:          a59eac3b-c56d-40a9-b433-972cdb48afa6

Filesystem magic number:  0xEF53

Filesystem revision #:    1 (dynamic)

Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super

Filesystem flags:         signed_directory_hash 

Default mount options:    user_xattr acl

Filesystem state:         clean

Errors behavior:          Continue

Filesystem OS type:       Linux

Inode count:              65536

Block count:              1048576

Reserved block count:     31457

Free blocks:              1029050

Free inodes:              65525

First block:              1

Block size:               1024

Fragment size:            1024

Reserved GDT blocks:      256

Blocks per group:         8192

Fragments per group:      8192

Inodes per group:         512

Inode blocks per group:   128

Filesystem created:       Mon Jul 12 23:36:08 2021

Last mount time:          n/a

Last write time:          Mon Jul 12 23:40:37 2021

Mount count:              0

Maximum mount count:      -1

Last checked:             Mon Jul 12 23:36:08 2021

Check interval:           0 (<none>)

Reserved blocks uid:      0 (user root)

Reserved blocks gid:      0 (group root)

First inode:              11

Inode size:           256

Required extra isize:     28

Desired extra isize:      28

Default directory hash:   half_md4

Directory Hash Seed:      89099a6f-887d-4624-88e4-97ad656b609e

[root@localhost ~]# 

(3)dumpe2fs: 显示文件属性信息

dumpe2fs [ -bfhixV ] [ -o superblock=superblock ] [ -o blocksize=blocksize ] device

    -h: 只显示超级块中的信息

[root@localhost ~]# dumpe2fs /dev/sdc

dumpe2fs 1.42.9 (28-Dec-2013)

Filesystem volume name:   DATA

Last mounted on:          <not available>

Filesystem UUID:          a59eac3b-c56d-40a9-b433-972cdb48afa6

Filesystem magic number:  0xEF53

Filesystem revision #:    1 (dynamic)

Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super

Filesystem flags:         signed_directory_hash 

Default mount options:    user_xattr acl

Filesystem state:         clean

Errors behavior:          Continue

Filesystem OS type:       Linux

Inode count:              65536

Block count:              1048576

Reserved block count:     31457

Free blocks:              1029050

Free inodes:              65525

First block:              1

Block size:               1024

Fragment size:            1024

Reserved GDT blocks:      256

Blocks per group:         8192

Fragments per group:      8192

Inodes per group:         512

Inode blocks per group:   128

Filesystem created:       Mon Jul 12 23:36:08 2021

Last mount time:          n/a

Last write time:          Mon Jul 12 23:40:37 2021

Mount count:              0

Maximum mount count:      -1

Last checked:             Mon Jul 12 23:36:08 2021

Check interval:           0 (<none>)

Reserved blocks uid:      0 (user root)

Reserved blocks gid:      0 (group root)

First inode:              11

Inode size:           256

Required extra isize:     28

Desired extra isize:      28

Default directory hash:   half_md4

Directory Hash Seed:      89099a6f-887d-4624-88e4-97ad656b609e

Group 0: (Blocks 1-8192)

  Primary superblock at 1, Group descriptors at 2-5

  Reserved GDT blocks at 6-261

  Block bitmap at 262 (+261), Inode bitmap at 263 (+262)

  Inode table at 264-391 (+263)

  7787 free blocks, 501 free inodes, 2 directories

  Free blocks: 406-8192

  Free inodes: 12-512

Group 1: (Blocks 8193-16384)

  Backup superblock at 8193, Group descriptors at 8194-8197

  Reserved GDT blocks at 8198-8453

  Block bitmap at 8454 (+261), Inode bitmap at 8455 (+262)

  Inode table at 8456-8583 (+263)

  7801 free blocks, 512 free inodes, 0 directories

  Free blocks: 8584-16384

  Free inodes: 513-1024

Group 2: (Blocks 16385-24576)

  Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)

  Inode table at 16387-16514 (+2)

  8062 free blocks, 512 free inodes, 0 directories

  Free blocks: 16515-24576

  Free inodes: 1025-1536

(4)fsck(file system check): 检查并修复Linux文件系统

    -t FSTYPE: 指定文件系统类型=fsck.FS_TYPE(FS_TYPE一定要与分区上已有文件类型相同)

    -a: 自动修复

[root@localhost ~]# blkid /dev/sdc

/dev/sdc: LABEL=”DATA” UUID=”a59eac3b-c56d-40a9-b433-972cdb48afa6″ TYPE=”ext2″ 

[root@localhost ~]# fsck.ext2 /dev/sdc

e2fsck 1.42.9 (28-Dec-2013)

DATA: clean, 11/65536 files, 19526/1048576 blocks

(5)e2fsck: 专用于修复ext2/ext3文件系统

    -f: 强制检查;(检查前需要先卸载设备)

    -p: 自动修复;

(6)mount:挂载

    挂载:将额外文件系统与根文件系统某现存的目录建立起关联关系,进而使得此目录成为其他文件访问入口的行为称之为是挂载。

    卸载:解除此关联关系的过程称之为卸载;

mount 设备 挂载点

 mount DEVICE MOUNT_POINT

        -o loop: 挂载本地回环设备

    mount /dev/sda5 /mnt/test

    设备:

        设备文件:/dev/sda5

        卷标:LABEL=“”

        UUID: UUID=“”

    dir,挂载点:目录

        要求:

            1、此目录没有被其它进程使用;

            2、目录得事先存在;

            3、目录中的原有的文件将会暂时隐藏(最好选择空文件夹进行挂载);

mount: 显示当前系统已经挂载的设备及挂载点

mount [options] [-o options] DEVICE MOUNT_POINT

    -a: 自动挂载所有支持自动挂载的设备,(在/etc/fstab文件中定义,且挂载选项中有自动挂载功能)

    -n: 任何设备挂载时,默认都会更新/etc/mtab,使用—n选项意味着挂载设备时,不把信息写入此文件;

    -t FSTYPE: 指定正在挂载设备上的文件系统的类型;不使用此选项时,mount会调用blkid命令获取对应文件系统的类型;

    -r: (readonly)只读挂载,挂载光盘时常用此选项

    -w: (read and write)读写挂载

-L:以LABEL指定挂载设备

-U:以UUID指定挂载设备

    -o: 指定额外的挂载选项,也即指定文件系统启用的属性;

async:异步模式(速度快)

sync:同步模式(数据更安全,速度慢得多)

remount: 重新挂载当前文件系统

ro: 挂载为只读

rw: 读写挂载

atime:(默认)每次访问文件/目录都会更新访问时间戳

noatime:访问文件/目录不会更新访问时间戳(一般关闭,对于访问非常多的文件能显著提高访问速度)

diratime/nodiratime:目录的访问时间戳

auto/noauto:是否支持自动挂载

exec/noexec:是否支持文件系统上的应用程序运行为进程

dev/nodev:是否支持在此文件系统上使用设备文件

suid/noosuid:是否允许此文件系统更改SUID(避免黑客通过系统更改SUID)

remount:重新挂载

user/nouser:是否允许用户挂载此设备

acl:启动此文件系统上的acl功能

注:上述选项可多个同时使用,彼此使用逗号分割,尽量避免普通用户挂载

默认挂载选项:defaults

 defaults

              Use default options: rw, suid, dev, exec, auto, nouser, and async.

DEVICE为要挂载的设备:

(1)设备文件:例如/dev/sda1

(2)卷标:-L ‘LABEL‘,例如 -L ‘MYDATA’

(3)UUID,-U  ‘UUID’

(4)伪文件系统名称:proc,sysfs,devtmpfs,configfs

挂载完成后,要通过挂载点访问对应文件系统上的文件;

(7)/etc/fstab

文件系统的配置文件/etc/fstab,OS在初始时,会自动用mount挂载此文件中每行定义的每个文件系统

每行定义一个要挂载的文件系统

    [neeq@gbiccxbrl ~]$ cat /etc/fstab

    #

    # /etc/fstab

    # Created by anaconda on Fri Dec 18 10:31:29 2015

    #

    # Accessible filesystems, by reference, are maintained under ‘/dev/disk’

    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

    #

要挂载的设备             挂载点                 文件系统类型    挂载选项        转储频率(备份频率)       文件系统自动检测次序

                                                                                                                                                                            (每多少天做一次完全备份)            (只有根可以为1)

    UUID=55b61d2f-b139-4336-a8ab-54389d9555a6 /                       ext4    defaults        1 1

    UUID=c49032e0-d885-4d14-91fd-ff973cea66c0 /boot                   ext4    defaults        1 2

    UUID=c31675c1-786c-479f-a6cf-01e263d2b4eb swap                    swap    defaults        0 0

    tmpfs                   /dev/shm                tmpfs   defaults        0 0

    devpts                  /dev/pts                devpts  gid=5,mode=620  0 0

    sysfs                   /sys                    sysfs   defaults        0 0

    proc                    /proc                   proc    defaults        0 0

    UUID=d9bf2e82-327b-488d-b606-55801d31a41d /svn                    ext4    defaults        1 1

    UUID=5999452a-7b86-42dc-8be9-fb31b0752f0b /webserver              ext4    defaults        1 1

fstab目录详解

要挂载的设备或伪文件系统:

设备文件,LABEL(LABEL=“”)、UUID(UUID=“”),伪文件系统名称(proc,sysfs)

挂载选项:

defaults

转储频率(一般不配置转储):

0:不做备份

1:每天转储

2:每隔一天转储

自检次序(一般不配置自检):

0:不自检

1:首先自检,一般只有rootfs才用1

mount -a:挂载/etc/fstab文件中定义的所有文件系统

fuser: 验正进程正在使用的文件或套接字文件

        -v: 查看某文件上正在运行的进程

        -k:杀死正在访问对应文件的进程

        -m:杀死正在访问挂载点的进程

    fuser -km MOUNT_POINT:终止正在访问此挂载点的所有进程

umount: 卸载某文件系统

    umount 设备/挂载点

    卸载注意事项:

        挂载的设备没有进程使用;

查看正在访问制定文件系统的用户

fuser -v /挂载点

清除正在访问此挂载点的所有进程

fuser -km /挂载点

24.3 swap分区及相关配置(非必要情况下建议不要使用交换分区)

    CPU多路复用通过:time slice

    X86CPU(32bit)当中

             Memory引入了虚拟地址,线性地址(每个进程认为自己有4G空间可用)

            对内存进行分页(page frame)

    如果内存满了,可以在硬盘上划分出一部分空间,将不常用的内存里面的进程移到硬盘当中

     这部分空间称之为是交换空间

    swap in:将内存里面的进程移到硬盘当中

    swap out:将硬盘里面的进程移到内存当中

    交换空间的存在使得内存可以过载使用

    Windows中称之为是虚拟内存

    linux中的交换分区为swap分区:

1、free

    查看当前系统的内存和虚拟内存使用情况 

    -m:以M为单位显示

    -h:进行单位换算

    [root@Daniel-R480 ~]# free

                  total        used        free      shared  buff/cache   available

    Mem:       33404872     6063620    27111900       17720      229352    27207520

    Swap:      31018612       70528    30948084

    [root@Daniel-R480 ~]# free -m

                  total        used        free      shared  buff/cache   available

    Mem:          32621        5922       26475          17         223       26568

    Swap:         30291          68       30222

    [root@Daniel-R480 ~]# free -h

                  total        used        free      shared  buff/cache   available

    Mem:            31G        5.8G         25G         17M        223M         25G

    Swap:           29G         68M         29G

    [root@Daniel-R480 ~]#

2、创建交换分区步骤:

(1)fdisk命令中,调整分区类型为82;

(2)mkswap /dev/sda8

-L LABEL

-U UUID

(3)启用或者关闭swap

swapon /dev/sda8(启用此设备中的交换空间)

-a:启用所有的定义在/etc/fstab文件中的交换设备

-p PRIORITY:指定优先级

swapoff /dev/sda8

3、回环设备及dd命令

    loopback, 使用软件来模拟实现硬件

    可使用回环设备来创建swap空间

    创建一个镜像文件,120G

dd命令:复制并转换文件

复制底层的数据流

if=数据来源

of=数据存储目标

bs=1(block size,复制的文件大小)

count=2(复制数目)

seek=#: 创建数据文件时,跳过的空间大小(可以用来创建虚假大小的文件,可以du来确认真实大小);

磁盘拷贝:

dd if=/dev/sda of=/dev/sdb

MBR的备份和还原    

    dd if=/dev/sda of=/mnt/usb/mbr.backup bs=512 count=1

    dd if=/mnt/usb/mbr.backup of=/dev/sda bs=512 count=1

破坏MBR中的bootloader:

dd if=/dev/zero of=/dev/sda bs=256 count=1

    创建一个大小为1024的镜像文件

    dd if=/dev/zero of=/var/swapfile bs=1M count=1024

    /dev/zero:可以无限的出0

    /dev/null:可以吞掉所有的数据

24.4 光盘挂载

挂载光盘设备

光盘设备文件:

IDE:/dev/hdc

SATA:/dev/sr0

符号链接文件:

/dev/cdrom

/dev/cdrw

/dev/dvd

/dev/dvdrw

mount -r /dev/cdrom /media/cdrom

unmount /dev/cdrom

练习:

1、创建一个2G的分区,文件系统为ext2,卷标为DATA,块大小为1024,预留管理空间为磁盘分区的8%;挂载至/backup目录,要求使用卷标进行挂载,且在挂载时启动此文件系统上的acl功能;

[root@localhost ~]# fdisk -l

#查看目前存在的硬盘,有sda,sdb,sdc,nvme0n1四块盘

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/sda: 107.4 GB, 107374182400 bytes, 209715200 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk label type: dos

Disk identifier: 0x000acbe0

   Device Boot      Start         End      Blocks   Id  System

/dev/sda1   *        2048     2099199     1048576   83  Linux

/dev/sda2         2099200   209715199   103808000   8e  Linux LVM

Disk /dev/mapper/centos-root: 53.7 GB, 53687091200 bytes, 104857600 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/centos-swap: 8455 MB, 8455716864 bytes, 16515072 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/nvme0n1: 21.5 GB, 21474836480 bytes, 41943040 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/centos-home: 44.1 GB, 44149243904 bytes, 86228992 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/sdc: 21.5 GB, 21474836480 bytes, 41943040 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

[root@localhost ~]# fdisk /dev/sdb

#选择sdb进行实验

Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.

Be careful before using the write command.

Device does not contain a recognized partition table

Building a new DOS disklabel with disk identifier 0xfa7592c5.

Command (m for help): n

#创建新的分区

Partition type:

   p   primary (0 primary, 0 extended, 4 free)

   e   extended

Select (default p): p

#选择基本分区或者是扩展分区,这里选择基本分区

Partition number (1-4, default 1): 1

First sector (2048-41943039, default 2048): 2048

#配置初始sector,默认即可

Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): 2g^H

#配置最后的sector,这个根据需求,按照标准来配置,前3个是错误示范

Value out of range.

Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): 2g

Value out of range.

Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): 2G

Value out of range.

Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): +2G

Partition 1 of type Linux and of size 2 GiB is set

Command (m for help): w

#保存退出

The partition table has been altered!

Calling ioctl() to re-read partition table.

Syncing disks.

[root@localhost ~]# partx /dev/sdb

#声明分区,让内核进行读取

NR START     END SECTORS SIZE NAME UUID

 1  2048 4196351 4194304   2G      

[root@localhost ~]# fdisk -l /dev/sdb

#检查分区是否正常识别

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk label type: dos

Disk identifier: 0xfa7592c5

   Device Boot      Start         End      Blocks   Id  System

/dev/sdb1            2048     4196351     2097152   83  Linux

#分区已经显示出来了,说明正常识别

[root@localhost ~]# mkfs.ext2 -L DATA -b 1024 -m 8 /dev/sdb1

#对分区进行格式化,配置文件系统

mke2fs 1.42.9 (28-Dec-2013)

Filesystem label=DATA

OS type: Linux

Block size=1024 (log=0)

Fragment size=1024 (log=0)

Stride=0 blocks, Stripe width=0 blocks

131072 inodes, 2097152 blocks

167772 blocks (8.00%) reserved for the super user

First data block=1

Maximum filesystem blocks=69206016

256 block groups

8192 blocks per group, 8192 fragments per group

512 inodes per group

Superblock backups stored on blocks: 

   8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409, 663553, 

   1024001, 1990657

Allocating group tables: done                            

Writing inode tables: done                            

Writing superblocks and filesystem accounting information: done   

[root@localhost ~]# mkdir /backup

#创建分区要挂载的位置,这里是/backup

mkdir: cannot create directory ‘/backup’: File exists

[root@localhost ~]# blkid /dev/sdb1

#查看分区情况

/dev/sdb1: LABEL=”DATA” UUID=”0a96b1d2-eebe-4245-82b9-612ff8cde44c” TYPE=”ext2″ 

[root@localhost ~]# mount -o acl /dev/sdb1 /backup

#挂载分区至/backup,并配置acl

[root@localhost ~]# df -h

#检查是否正常挂载,出现sdb1即说明正常挂载

Filesystem               Size  Used Avail Use% Mounted on

/dev/mapper/centos-root   50G  2.6G   48G   6% /

devtmpfs                 3.9G     0  3.9G   0% /dev

tmpfs                    3.9G     0  3.9G   0% /dev/shm

tmpfs                    3.9G  8.7M  3.9G   1% /run

tmpfs                    3.9G     0  3.9G   0% /sys/fs/cgroup

/dev/mapper/centos-home   42G   33M   42G   1% /home

/dev/sda1               1014M  143M  872M  15% /boot

tmpfs                    781M     0  781M   0% /run/user/0

/dev/sdb1                2.0G  3.1M  1.9G   1% /backup

[root@localhost ~]# 

2、将此文件系统的超级块中的信息中包含了block和inode的行保存至/tmp/partition.txt中;

#两个语句效果一样,选择一个进行执行即可,之后可以通过vim查看执行结果

[root@localhost ~]# dumpe2fs -h /dev/sdb1 | egrep -i  “block|inode” >> /tmp/partition.txt  

dumpe2fs 1.42.9 (28-Dec-2013)

[root@localhost ~]# vim /tmp/partition.txt 

[root@localhost ~]# tune2fs -l /dev/sdb1 | egrep -i  “block|inode” >> /tmp/partition.txt  

[root@localhost ~]# vim /tmp/partition.txt 

[root@localhost ~]# 

3、复制/etc目录中的所有文件至此文件系统;而后调整此文件系统类型为ext3,要求不能损坏已经复制而来的文件;

[root@localhost ~]# cp -r /etc/* /backup/

[root@localhost ~]# tune2fs -j  /dev/sdb1

tune2fs 1.42.9 (28-Dec-2013)

Creating journal inode: done

[root@localhost ~]# blkid /dev/sdb1

#查看分区类型

/dev/sdb1: LABEL=”DATA” UUID=”0a96b1d2-eebe-4245-82b9-612ff8cde44c” SEC_TYPE=”ext2″ TYPE=”ext3″ 

[root@localhost ~]# ls /backup/

#查看文件是否备份过来

4、调整其预留百分比为3%;

[root@localhost ~]# tune2fs -m 3 /dev/sdb1

tune2fs 1.42.9 (28-Dec-2013)

Setting reserved blocks percentage to 3% (62914 blocks)

[root@localhost ~]# 

5、以重新挂载的方式挂载此文件系统为不更新访问时间戳,并验正其效果;

[root@localhost ~]# stat /backup/inittab 

#当前时间戳

  File: ‘/backup/inittab’

  Size: 511          Blocks: 2          IO Block: 1024   regular file

Device: 811h/2065d   Inode: 53          Links: 1

Access: (0644/-rw-r–r–)  Uid: (    0/    root)   Gid: (    0/    root)

Context: unconfined_u:object_r:unlabeled_t:s0

Access: 2021-07-13 22:05:24.964712195 -0400

Modify: 2021-07-13 22:05:24.984712387 -0400

Change: 2021-07-13 22:05:24.984712387 -0400

 Birth: –

[root@localhost ~]# cat /backup/inittab 

#cat一下,修改时间戳

# inittab is no longer used when using systemd.

#

# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

#

# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target

#

# systemd uses ‘targets’ instead of runlevels. By default, there are two main targets:

#

# multi-user.target: analogous to runlevel 3

# graphical.target: analogous to runlevel 5

#

# To view current default target, run:

# systemctl get-default

#

# To set a default target, run:

# systemctl set-default TARGET.target

#

[root@localhost ~]# stat /backup/inittab 

#stat可以看到accesstime更新了

  File: ‘/backup/inittab’

  Size: 511          Blocks: 2          IO Block: 1024   regular file

Device: 811h/2065d   Inode: 53          Links: 1

Access: (0644/-rw-r–r–)  Uid: (    0/    root)   Gid: (    0/    root)

Context: unconfined_u:object_r:unlabeled_t:s0

Access: 2021-07-13 22:16:20.348151973 -0400

Modify: 2021-07-13 22:05:24.984712387 -0400

Change: 2021-07-13 22:05:24.984712387 -0400

 Birth: –

[root@localhost ~]# mount -o remount,noatime /backup/

#重新挂载为accesstime不随访问更改的系统

[root@localhost ~]# cat /backup/inittab

#cat测试,此时时间戳应该不会变 

# inittab is no longer used when using systemd.

#

# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

#

# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target

#

# systemd uses ‘targets’ instead of runlevels. By default, there are two main targets:

#

# multi-user.target: analogous to runlevel 3

# graphical.target: analogous to runlevel 5

#

# To view current default target, run:

# systemctl get-default

#

# To set a default target, run:

# systemctl set-default TARGET.target

#

[root@localhost ~]# stat /backup/inittab

#stat测试,时间戳确实没变

  File: ‘/backup/inittab’

  Size: 511          Blocks: 2          IO Block: 1024   regular file

Device: 811h/2065d   Inode: 53          Links: 1

Access: (0644/-rw-r–r–)  Uid: (    0/    root)   Gid: (    0/    root)

Context: unconfined_u:object_r:unlabeled_t:s0

Access: 2021-07-13 22:16:20.348151973 -0400

Modify: 2021-07-13 22:05:24.984712387 -0400

Change: 2021-07-13 22:05:24.984712387 -0400

 Birth: –

[root@localhost ~]# 

6、对此文件系统强行做一次检测;

[root@localhost ~]# e2fsck -f /dev/sdb1

e2fsck 1.42.9 (28-Dec-2013)

/dev/sdb1 is mounted.

e2fsck: Cannot continue, aborting.

[root@localhost ~]# umount /dev/sdb1

[root@localhost ~]# e2fsck -f /dev/sdb1

e2fsck 1.42.9 (28-Dec-2013)

Backing up journal inode block information.

Moving journal from /.journal to hidden inode.

Pass 1: Checking inodes, blocks, and sizes

Pass 2: Checking directory structure

Pass 3: Checking directory connectivity

Pass 4: Checking reference counts

Pass 5: Checking group summary information

DATA: ***** FILE SYSTEM WAS MODIFIED *****

DATA: 2372/131072 files (5.6% non-contiguous), 97234/2097152 blocks

[root@localhost ~]# 

7、删除复制而来的所有文件,并将此文件系统重新挂载为同步(sync);而后再次复制/etc目录中的所有文件至此挂载点,体验其性能变化;

[root@localhost ~]# mount /dev/sdb1 /backup/

[root@localhost ~]# mount -o remount,sync /backup

[root@localhost ~]# cp -ru /etc/* /backup/

[root@localhost ~]# cd 

23、磁盘及文件系统详解

23.1 磁盘管理(IO设备):

机械式硬盘:

    Cylinder:柱面

    分区是磁盘的逻辑边界

    磁盘刚出场时进行低级格式化,没有进行分区,创建磁道

    高级格式化:格式化以后可以创建文件系统

    Partition(分区):划分文件系统

    MBR(主引导记录):在零柱面,一般为512字节

        Master Boot Record

        Main Boot Record

                       446bytes:BootLoader,引导程序

                        64bytes:

                              16bytes:表示一个分区

                               前三个可以是主分区,第四个可以是扩展分区(指向其他地方的指针)

                                只能有四个分区,扩展分区只能有一个,扩展分区下的分区称之为是逻辑分区,逻辑分区可以有多个

                        2bytes:Magic Number

                              标记MBR是否有效    

    划分分区按柱面进行划分

    磁盘读写延迟,由硬盘的转速来决定,转速越快性能越好

    硬盘盘芯为真空,因为转速过快,要挡住灰尘,避免高温 

    文件系统是个管理软件,将磁盘划分为元数据(定义数据的编号和位置)和数据存储区

    位图(bitmap):

        用来确认存储空间使用情况的文件

             分为Inode bitmap和block bitmap

    Inode(Index Node):

        索引节点,存储和文件内容无关的文件信息

地址指针:

直接指针:

间接指针:

三级指针:

[root@localhost ~]# dumpe2fs /dev/sdb1 | tail -10

dumpe2fs 1.42.9 (28-Dec-2013)

  Inode table at 2080771-2080898 (+2)

  8059 free blocks, 492 free inodes, 3 directories

  Free blocks: 2080902-2088960

  Free inodes: 130069-130560

Group 255: (Blocks 2088961-2097151)

  Block bitmap at 2088961 (+0), Inode bitmap at 2088962 (+1)

  Inode table at 2088963-2089090 (+2)

  8061 free blocks, 512 free inodes, 0 directories

  Free blocks: 2089091-2097151

  Free inodes: 130561-131072

[root@localhost ~]# 

Inode bitmap:对应标识每个inode空闲与否的状态信息

  每个文件系统支持的单个文件的大小是不一样的

    目录:

        存储Inode号码和文件名

    尽可能让磁盘里面的文件使用连续的磁盘块,可以减少磁盘碎片,这样可以提升访问文件的速度

    创建分区会首先创建许多个块组

    块组:

        很多个小的逻辑分区,每个块组都有自己的块位图,Inode位图等信息

    Super block:

             保存全局信息,块组信息,inode信息

    block(块):一个大小一般为1024(1K),有的也为,2048(2K)或4096(4K)

    固态硬盘、U盘、光盘、软盘、硬件、磁带

23.2 链接文件

    链接文件:分为硬链接和符号连接

/etc/abc –à/usr/local/abc

    ln [-s -v] SRC DEST

-s代表软连接,不带任何选项代表硬链接,

-v(verbose)代表显示创建过程

    硬链接:直接指向同一个Inode的不同路径

    硬链接:

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

        2、不能跨文件系统;

        3、创建硬链接会增加文件被链接的次数(指向同一个inode的多个不同路径);

    符号连接:直接指向另一个文件的文件路径   

    符号链接:

        1、可应用于目录;

        2、可以跨文件系统,跨分区进行;

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

        4、指向的是另一个文件的路径,其大小为指定的路径所包含的字符个数;

[root@localhost ~]# ln anaconda-ks.cfg a

[root@localhost ~]# ls -a

.   a                .bash_history  .bash_profile  .cshrc             .tcshrc

..  anaconda-ks.cfg  .bash_logout   .bashrc        .oracle_jre_usage  .viminfo

[root@localhost ~]# ll

total 8

-rw——-. 2 root root 1426 May 27 06:31 a

-rw——-. 2 root root 1426 May 27 06:31 anaconda-ks.cfg

[root@localhost ~]# ls -li

total 8

100663375 -rw——-. 2 root root 1426 May 27 06:31 a

100663375 -rw——-. 2 root root 1426 May 27 06:31 anaconda-ks.cfg

[root@localhost ~]# ln -s anaconda-ks.cfg b

[root@localhost ~]# ll -a

total 40

dr-xr-x—.  3 root root  194 Jul 21 21:46 .

dr-xr-xr-x. 17 root root  224 May 27 06:31 ..

-rw——-.  2 root root 1426 May 27 06:31 a

-rw——-.  2 root root 1426 May 27 06:31 anaconda-ks.cfg

lrwxrwxrwx.  1 root root   15 Jul 21 21:46 b -> anaconda-ks.cfg

-rw——-.  1 root root 4056 Jul 12 01:58 .bash_history

-rw-r–r–.  1 root root   18 Dec 28  2013 .bash_logout

-rw-r–r–.  1 root root  176 Dec 28  2013 .bash_profile

-rw-r–r–.  1 root root  176 Dec 28  2013 .bashrc

-rw-r–r–.  1 root root  100 Dec 28  2013 .cshrc

drwxr-xr-x.  2 root root   40 May 27 06:54 .oracle_jre_usage

-rw-r–r–.  1 root root  129 Dec 28  2013 .tcshrc

-rw——-.  1 root root 6448 May 31 02:46 .viminfo

[root@localhost ~]# ls -li

total 8

100663375 -rw——-. 2 root root 1426 May 27 06:31 a

100663375 -rw——-. 2 root root 1426 May 27 06:31 anaconda-ks.cfg

100663380 lrwxrwxrwx. 1 root root   15 Jul 21 21:46 b -> anaconda-ks.cfg

[root@localhost ~]# 

df :查看磁盘及文件系统占用

-h:human-readable

-i:ibodes instead of blocks

-P:以Posix兼容的格式输出

du:查看某目录总体空间占用状态:

-h:human-readable进行格式转换

-s:summary查看目录整体大小

[root@localhost ~]# df -h

Filesystem               Size  Used Avail Use% Mounted on

/dev/mapper/centos-root   50G  2.6G   48G   6% /

devtmpfs                 3.9G     0  3.9G   0% /dev

tmpfs                    3.9G     0  3.9G   0% /dev/shm

tmpfs                    3.9G  8.7M  3.9G   1% /run

tmpfs                    3.9G     0  3.9G   0% /sys/fs/cgroup

/dev/sda1               1014M  143M  872M  15% /boot

/dev/mapper/centos-home   42G   33M   42G   1% /home

tmpfs                    781M     0  781M   0% /run/user/0

/dev/sdc2                 33M  782K   30M   3% /mydata

[root@localhost ~]# du -h

4.0K    ./.oracle_jre_usage

44K .

[root@localhost ~]# du -sh

44K .

[root@localhost ~]# 

23.3 设备文件:

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

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

    常见的设备

        b(块设备): 硬盘

        c(字符设备): 键盘

1、位置(/dev)

    [root@Daniel-R480 ~]# ls -lh /dev

    total 0

    drwxr-xr-x 1 root root     4.0K Jun 17 09:19 block

    lrwxrwxrwx 1 root root       13 Jun 17 09:19 fd -> /proc/self/fd

    crw-r–r– 1 root root   1,  11 Jun 17 09:19 kmsg

    crw-rw-rw- 1 root root  10,  50 Jun 17 09:19 lxss

    crw-rw-rw- 1 root root   1,   3 Jun 17 09:19 null

    crw-rw-rw- 1 root tty    5,   2 Jun 17 09:44 ptmx

    设备文件中间的两个数字为主设备号,次设备号,其无大小,存储主次设备号在inode中

        主设备号 (major number)

            标识设备类型

        次设备号 (minor number)

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

2、mknod(创建设备文件)

mknod [OPTION]… NAME TYPE [MAJOR MINOR]

    -m MODE指定权限

    [root@Daniel-R480 ~]# mknod -m 640 mydev2 c 66 0

    [root@Daniel-R480 ~]# ls -l

    total 32

    lrwxrwxrwx 1 root  root     1 Jun 17 10:42 abc -> a

    -rwxr-xr-x 1 root  root   230 Jun  9 14:50 addusers.sh

    -rwxr-xr-x 1 root  root   591 Jun 16 17:32 adminusers2.sh

    -rwxr-xr-x 1 root  root  1140 Jun 17 09:21 adminusers3.sh

    -rwxr-xr-x 1 root  root   559 Jun  9 15:21 adminusers.sh

    -rw——- 1 root  root  6921 Jan 29  2019 anaconda-ks.cfg

    -rw-r–r– 1 user2 root     0 Jun  9 17:32 b

    -rw-r–r– 1 root  root     0 Jun  9 17:32 c

    -rwxr-xr-x 1 root  root   106 Jun  9 10:01 calc.sh

    -rw-r–r– 1 root  root     0 Jun  9 17:32 d

    -rwxr-xr-x 1 root  root   173 Jun  9 14:55 delusers.sh

    -rwxr-xr-x 1 root  root   158 Jun 16 17:21 list2.sh

    -rwxr-xr-x 1 root  root   127 Jun 16 17:23 list.sh

    crw-r–r– 1 root  root 66, 0 Jun 17 11:01 mydev

    crw-r—– 1 root  root 66, 0 Jun 17 11:01 mydev2

    -rw——- 1 root  root  6577 Jan 29  2019 original-ks.cfg

    -rwxr-xr-x 1 root  root   250 Jun  9 09:43 quit.sh

    -rwxr-xr-x 1 root  root   562 Jun 17 09:37 showlogged.sh

    -rwxr-xr-x 1 root  root   198 Jun 16 17:31 sys.sh

    -rwxr-xr-x 1 root  root     0 Jun  8 17:50 test

    -rwxr-xr-x 1 root  root    87 Jun  9 10:36 testuser.sh

可以通过设备文件向某个设备直接传输数据

    [root@Daniel-R480 ~]# tty

    /dev/pts/0

    [root@Daniel-R480 ~]# echo hello >>/dev/pts/1

    [root@Daniel-R480 ~]# 

    #另一个终端下

    [root@Daniel-R480 ~]# tty

    /dev/pts/1

    [root@Daniel-R480 ~]# hello

3、硬盘设备的设备文件名:

    设备文件名和硬盘的接口类型有关

    IDE, ATA:hd

    SATA:sd

    SCSI: sd

    USB: sd

        a,b,c,…来区别同一种类型下的不同设备

    IDE: 一般PC机上只有两个IDE口,每个口上可以接两块盘

    分区方案

        第一个IDE口:主、从

                   /dev/hda, /dev/hdb

        第二个IDE口:主、从

                  /dev/hdc, /dev/hdd

    SATA/SCSI/USB分区方案

    sda, sdb, sdc, …

    hda: (IDE硬盘)

        hda1: 第一个主分区

        hda2: 

        hda3:

        hda4:

        hda5: 第一个逻辑分区(只能从hda5开始)

4、fdisk

(1)fdisk -l [/dev/to/some_device_file]

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

[root@localhost dev]# fdisk -l

Disk /dev/sda: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/sdb: 107.4 GB, 107374182400 bytes, 209715200 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk label type: dos

Disk identifier: 0x000acbe0

   Device Boot      Start         End      Blocks   Id  System

/dev/sdb1   *        2048     2099199     1048576   83  Linux

/dev/sdb2         2099200   209715199   103808000   8e  Linux LVM

Disk /dev/mapper/centos-root: 53.7 GB, 53687091200 bytes, 104857600 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/centos-swap: 8455 MB, 8455716864 bytes, 16515072 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/nvme0n1: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/sdc: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/centos-home: 44.1 GB, 44149243904 bytes, 86228992 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

[root@localhost dev]# 

(2)管理磁盘分区:

fdisk /dev/sda(对于一块硬盘来说,最多只能管理15分区)

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

    n: 创建新分区

        e: 扩展分区

        p: 主分区

    d: 删除一个分区

    w: 保存退出

    q: 不保存退出

    t: 修改分区类型

        L: 显示所有支持的分区类型

    l: 显示所支持的所有分区类型(在t命令里面用L)

[root@localhost ~]# fdisk /dev/sdc

Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.

Be careful before using the write command.

Command (m for help): p

Disk /dev/sdc: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk label type: dos

Disk identifier: 0x06bd6860

   Device Boot      Start         End      Blocks   Id  System

Command (m for help): n

Partition type:

   p   primary (0 primary, 0 extended, 4 free)

   e   extended

Select (default p): p

Partition number (1-4, default 1): 1

First sector (2048-2097151, default 2048): 2048

Last sector, +sectors or +size{K,M,G} (2048-2097151, default 2097151): 1000000

Partition 1 of type Linux and of size 487.3 MiB is set

Command (m for help): p

Disk /dev/sdc: 1073 MB, 1073741824 bytes, 2097152 sectors

Units = sectors of 1 * 512 = 512 bytes

Sector size (logical/physical): 512 bytes / 512 bytes

I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk label type: dos

Disk identifier: 0x06bd6860

   Device Boot      Start         End      Blocks   Id  System

/dev/sdc1            2048     1000000      498976+  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.

(3)查看内核是否已经识别新的分区

[root@localhost ~]# cat /proc/partitions | grep sdc

   8       32    1048576 sdc

   8       33     498976 sdc1

[root@localhost ~]# 

(4)partx:新版系统常用(通知内核重新读取硬盘分区表)

partx -a /dev/DEVICE

-n M:N(指定开始结束的位置,也可写为M:,:N)

kpartx -a /dev/DEVICE

-f:force(强制添加,风险比较大,尽量不使用)

CentOS 5

partprobe [/dev/device]:也可以用来修改分区 

5、判断文件状态

if [[ ! -s filename ]] <==如果文件存在且为空,-s代表存在不为空,!将他取反

then

ok

fi

-s 表示文件是否存在并且是否为非空

判断文件的参数如下

    -e 文件存在      

    -f file 是一个 regular 文件(不是目录或者设备文件)

    -s 文件长度不为 0

    -d 文件是个目录

    -b 文件是个块设备(软盘,cdrom 等等) 

    -c 文件是个字符设备(键盘,modem,声卡等等) 

     -p 文件是个管道

     -h 文件是个符号链接

    -L 文件是个符号链接

    -S 文件是个 socket

    -t 关联到一个终端设备的文件描述符,这个选项一般都用来检测是否在一个给定脚本中的 stdin[-t0]或[-t1]是一个终端

    -r 文件具有读权限(对于用户运行这个 test) 

     -w 文件具有写权限(对于用户运行这个 test) 

    -x 文件具有执行权限(对于用户运行这个 test)

6、文件操作

文件删除

文件复制

文件移动

练习:写一个脚本

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

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

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

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

#!/bin/bash

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

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

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

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

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

说明:

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

#!/bin/bash

# Author: Jerry(jerry@magedu.com)

# Date: 2013-03-08 18:05

# Description: Create a bash script file head.

# Version: 0.1

#

    #/bin/bash

    #

    #判断FILE是否存在

    FI=0

    #判断FILE是否为空

    FIL=0

    #添加作者

    AUT=0

    #date

    DAT=0

    #description

    DES=0

    #VERSION

    VER=0

    for I in `seq 0 $#`; do

      if [ $# -gt 0 ];then

       case $1 in

         -f|–file)

            FILE=$2

            if [ -e $FILE ];then

                   FI=1

               if [ -s $FILE ];then

                   FIL=1

               fi

            else

               echo -e “$FILE is no exist.\n mkscripts exitting…”

               exit 1

            fi

             shift 2;;

         -a)

            #if [ $FI -eq 1 ] && [ FIL -eq 0 ];then

               AUT=1

               AUTH=$2

            #fi

               shift 2;;

         -t)

            #if [ $FI -eq 1 ] && [ FIL -eq 0 ];then        

               DAT=1

               DATE=$2

            #fi

               shift 2;;

         -d)

            #if [ $FI -eq 1 ] && [ FIL -eq 0 ];then

               DES=1

               DESC=$2

            #fi

               shift 2;;

         -v)

            #if [ $FI -eq 1 ] && [ FIL -eq 0 ];then

               VER=1

               VERS=$2

           #fi

               shift 2;;

         -h)

            echo “Usage is :`basename $0` -v|–version VERSION -a|–author AUTHOR -t|–time DATETIME -d|–description DESCRIPTION -f|–file /PATH/TO/FILE -h|–help”

            exit 0;;

         *)

            echo “Usage is :`basename $0` -v|–version VERSION -a|–author AUTHOR -t|–time DATETIME -d|–description DESCRIPTION -f|–file /PATH/TO/FILE -h|–help”

            exit 2;;

       esac

      else

        break

      fi

    done

    #初始化配置

    if [ $FIL == 1 ];then

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

          vim $FILE

          exit 0

        else

          echo “This is not a script.”

          exit 3

        fi

    else

       echo “#!/bin/bash” >> $FILE

    fi

    if [ $AUT == 1 ];then

        echo “#Auther:$AUTH” >> $FILE

    fi

    if [ $DAT == 1 ];then

        echo “#Date:$DATE” >> $FILE

    fi

    if [ $DES == 1 ];then

        echo “#Description:$DESC” >> $FILE

    fi

    if [ $VER == 1 ];then

        echo “#Version:$VERS” >> $FILE

    fi

22、bash脚本编程之五 case语句及脚本选项进阶

22.1 选择结构:

1、if语句

单分支、

    if: 

    if CONDITION; then

      statement

      …

    fi

    双分支、

    if CONDITION; then

      statement

      …

    else

      statement

      …

    fi

多分支

    if CONDITION1; then

      statement

      …

    elif CONDITION2; then

      statement

      …

    esle

      statement

      …

    fi

2、case语句:选择结构

    case SWITCH in 

    value1)

      statement

      …

      ;;

    value2)

      statement

      ..

      ;;

    *)

      statement

      …

      ;;

    esac

例1

    a-z

    A-Z

    0-9

    [abc]

    输出不同的对应结果

    #!/bin/bash

    #

    case $1 in

    [A-Z])

            echo “upper”;;

    [a-z])

            echo “lower”;;

    [0-9])

            echo “number”;;

    *)

            echo “wrong input”;;

    esac

例2

    只识别参数start,stop,restart,status其中之一

    #!/bin/bash

    #

    case $1 in

    start)

       echo start;;

    stop)

       echo stop;;

    restart)

       echo restart;;

    status)

       echo status;;

    *)

       echo “The usage is `basename $0` {start|stop|restart|status}”;;

    esac

例3

写一个脚本,可以接受选项及参数,而后能获取每一个参数,及选项的参数,并能根据选项做出特定的操作,比如

adminusers.sh –add tom.jerry –del tom,jerry -v|–verbose -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

例4

练习:写一个脚本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

21、文件系统访问控制列表FACL

练习:写一个脚本

写一个脚本,显示当前系统上shell为-s指定类型的用户,并统计其用户总数。-s选项后面跟的参数必须是/etc/shells文件中存在的shell类型,否则不执行此脚本。另外,此脚本还可以接受–help选项,以显示帮助信息。脚本执行形如:

./showshells.sh -s bash

显示结果形如:

BASH,3users,they are:

root,redhat,gentoo

#!/bin/bash

#

if [ $1 == ‘-s’ ]; then

  ! grep “${2}$” /etc/shells &> /dev/null && echo “Invalid shell.” && exit 7

elif [ $1 == ‘–help’ ];then

  echo “Usage: showshells.sh -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”

${变量名}

21.1 文件系统访问控制列表:

tom:

    tom, tom基本组

jerry: other:r–

想让jerry访问tom创建的文件,并且不让其他人访问

FACL:Filesystem Access Control List(文件系统访问控制列表)

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

jerry: rw-

21.1.1 FACL配置

(1)setfacl(设置FACL)

-m: 设定

u:UID:perm

g:GID:perm

-x:取消

u:UID

g:GID

(2)getfacl(查看FACL)

21.2 几个命令:

w:

查看当前登录到系统上的用户及其在处理的事情

who:

查看当前登录到系统上的用户及其登录信息

[root@Daniel-LASV ~]# who

root     pts/0        2021-06-10 01:58 (116.228.4.126)

[root@Daniel-LASV ~]# w

 01:59:05 up 215 days, 18:16,  1 user,  load average: 0.03, 0.01, 0.00

USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT

root     pts/0    116.228.4.126    01:58    1.00s  0.00s  0.00s w

[root@Daniel-LASV ~]# 

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

sleep :

让进程延迟几秒钟

whoami:

当前系统的有效用户

last:

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

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

    [root@Daniel-R480 tmp]# last -4

    root     pts/1        localhost        Thu Jun 10 09:54   still logged in   

    root     pts/0        localhost        Thu Jun 10 09:03   still logged in   

    root     pts/1        localhost        Wed Jun  9 17:16 – 09:54  (16:37)    

    root     pts/0        localhost        Wed Jun  9 17:04 – 09:03  (15:59)    

    wtmp begins Wed Jun  9 14:30:27 2021

lastb:

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

-n #:

    [root@Daniel-SHSH ~]# lastb -3

    root     ssh:notty    65.78.170.48     Tue Jun  8 21:12 – 21:12  (00:00)    

    root     ssh:notty    65.78.170.48     Tue Jun  8 21:12 – 21:12  (00:00)    

    root     ssh:notty    65.78.170.48     Tue Jun  8 21:12 – 21:12  (00:00)    

    btmp begins Sat Jun  5 01:06:32 2021

lastlog: 

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

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

    [root@Daniel-R480 tmp]# lastlog -u daniel

    Username         Port     From             Latest

    daniel           pts/1                     Thu Jun 10 09:58:18 +0800 2021

basename:

    $0: 执行脚本时的脚本路径及名称

    [root@Daniel-R480 ~]# basename ./quit.sh 

    quit.sh

mail:

查看邮件

[root@Daniel-SHSH ~]# mail

No mail for root

hostname: 

       显示主机名

[root@Daniel-SHSH ~]# hostname

Daniel-SHSH

[root@Daniel-SHSH ~]# echo $HOSTNAME

Daniel-SHSH

[root@Daniel-R480 ~]# hostname test

[root@Daniel-R480 ~]# hostname

test

[root@Daniel-R480 ~]# su – root

Last login: Thu Jun 10 09:58:28 CST 2021 on tty1

[root@test ~]# 

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

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

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

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

生成随机数

RANDOM: 0-32768

[daniel@Daniel-R480 ~]$ echo $RANDOM

20744

linux下的随机数生成器:熵池

/dev/random:

/dev/urandom:

终端类型:

console:控制台

pty:物理终端(通过VGA连接)

tty:虚拟终端(通过vga连接)

ttys:串行终端

pts/#:伪终端

写一个脚本,利用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

20、文件查找

grep, egrep, fgrep: 文本查找

20.1 命令

文件查找:

1、locate:

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

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

速度快

2、find:

实时,精确,支持众多查找标准

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

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

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

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

处理运作:默认为显示

匹配标准:

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

文件名通配:

*:任意长度的任意字符

?

[]

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

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

-user USERNAME: 根据属主查找

-group GROUPNAME: 根据属组查找

-uid UID: 根据UID查找

-gid GID: 根据GID查找

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

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

-type :根据文件类型来查找

f: 普通文件

d:目录

c:字符设备

b:块设备

l:链接文件,附加链接

p:管道设备

s:套接字设备

-size [+|-]:指定查找时的文件大小,不跟单位默认为字节,+代表大于,-代表小于,模糊统计,接近的数值都会被匹配

#k:表示kb

#M:表示M

#G:表示G

20.2 组合条件:

-a:与

-o:或

-not :非

/tmp目录,不是目录,并且还不能套接字类型的文件

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

find ./ -not \( -user user1 -o -user user2 \)

find ./ -not -user user1 -a -not -user user2

-mtime:根据修改时间进行查找(默认为天)

-ctime:改变时间

-atime:访问时间

[+|-]#:(+)至少,(-)至多

-mmin:根据修改分钟进行查找

-cmin:改变分钟

-amin:访问分钟

[+|-]#:(+)至少,(-)至多

-perm MODE:精确匹配文件权限

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

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

-644

644: rw-r–r–

755: rwxr-xr-x

750: rwxr-x—

find ./ -perm -001查找其他用户有执行权限的文件

20.3 运作:

-print: 显示(为默认)

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

-ok COMMAND {} \; 每一次操作都需要用户确认({}表示引用原先文件的文件名)

-exec COMMAND {} \;操作不需要用户确认

xargs命令比-exec更强大,更复杂

练习

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        

19、vim编辑器

文本编辑器,字处理器

ASCII

简单的文本编辑器nano, sed

vi: Visual Interface

vim: VI iMproved(vi的增强版)

vimtutor:vim练习文档

vi为全屏编辑器,模式化编辑器

19.1 vim的模式及模式转换

    vim模式:

    编辑模式(命令模式):所有的命令作为编辑文档的操作

    输入模式:所有输入都默认用来直接输入为文本

    末行模式:可以输入很多编辑模式不支持的文件管理命令

    模式转换:

    编辑–>输入:

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

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

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

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

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

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

    输入–>编辑:

        ESC

    编辑–>末行:

        :

    末行–>编辑:

        ESC, ESC(一次或两次,有时需要敲两下)

19.2 打开及关闭文件

19.2.1打开文件

    # vim /path/to/somefile

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

        [root@Daniel-R480 ~]# vim +3 testuser.sh

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

        [root@Daniel-R480 ~]# vim + testuser.sh

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

            [root@Daniel-R480 ~]# vim +/echo testuser.sh

        默认处于编辑模式

19.2.2 关闭文件(只能在编辑模式或者末行模式关闭)

1、末行模式关闭文件

                     :q  退出

                     :wq 保存并退出

                     :q! 不保存并退出

                     :w 保存

                     :w! 强行保存

                     :wq –> 😡

    2、编辑模式下退出

                      ZZ: 保存并退出

19.3 移动光标和翻屏

19.3.1 移动光标(编辑模式)

    1、逐字符移动:

        h: 左

        l: 右

        j: 下

        k: 上

     #h: 移动#个字符;

    2、以单词为单位移动

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

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

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

        #w: 移动至第#个单词的词首

    3、行内跳转:

        0: 绝对行首

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

        $: 绝对行尾

    4、行间跳转

        #G:跳转至第#行;

        G:最后一行

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

19.3.2  翻屏

Ctrl+f: 向下翻一屏

Ctrl+b: 向上翻一屏

Ctrl+d: 向下翻半屏

Ctrl+u: 向上翻半屏

19.4 内容处理

19.4.1 删除单个字符

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

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

19.4.2 删除命令: d

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

          #dw, #de, #db

          dd: 删除当前光标所在行

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

    末行模式下:

    StartADD,EndADDd(起始地址到末地址加上d)

         .: 表示当前行

         $: 最后一行

         +#: 向下的#行

    删除的内容会被保存在缓冲区当中,可暂时保存

19.4.3 粘贴命令 p

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

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

19.4.4 复制命令 y

    用法同d命令

    Vim中如何全选并复制?(区分大小写!!!)

    全部删除:按esc键后,先按gg(到达顶部),然后dG

    全部复制:按esc键后,先按gg,然后ggyG

    全选高亮显示:按esc键后,先按gg,然后ggvG或者ggVG

    单行复制:按esc键后,然后yy

    单行删除:按esc键后,然后dd

    粘贴:按esc键后,然后p

    From <https://zhuanlan.zhihu.com/p/51360394

19.4.5 修改:

先删除内容,再转换为输入模式

c: 用法同d命令

19.4.6 替换:r

R:进入替换模式

19.4.7 撤消编辑操作 u

u:撤消前一次的编辑操作(连续u命令可撤消此前的n次编辑操作)

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

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

19.4.8 重复前一次编辑操作

.:输入.命令可直接实现

19.5 可视化模式及查找替换

19.5.1 可视化模式

v: 按字符选取

V:按矩形选取

19.5.2 查找

/PATTERN:从当前光标向文件尾部查找

?PATTERN:从当前光标向文件尾部查找

n:查看下一个

N:查看上一个

19.5.3 查找并替换

在末行模式下使用s命令

    ADDR1,ADDR2s@PATTERN@string@gi(起始结束地址+s@初始字符@要替换的字符@,其中@也可以用/替换)(g全局替换,i忽略大小写)

1,$:表示第一行到最后一行

%:表示全文

练习:

将/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

19.6 文件选择和显示方案

19.6.1 使用vim编辑多个文件

vim FILE1 FILE2 FILE3

:next 切换至下一个文件

:prev 切换至前一个文件

:last 切换至最后一个文件

:first 切换至第一个文件

退出

:qa 全部退出

19.6.2 分屏显示一个文件

Ctrl+w, s: 水平拆分窗口

Ctrl+w, v: 垂直拆分窗口

在窗口间切换光标:

Ctrl+w, ARROW        

:qa 关闭所有窗口

19.6.3 分窗口编辑多个文件

vim -o : 水平分割显示

vim -O : 垂直分割显示

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

末行模式下使用w命令

:w

:ADDR1,ADDR2w /path/to/somewhere

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

:r /path/to/somefile

19.6.6 跟shell交互

:! COMMAND

19.7 高级操作

19.7.1 显示或取消显示行号

显示行号

:set number

:set nu

取消显示行号

    :set nonu

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

忽略

:set ignorecase

:set ic

区分

:set noic

19.7.3 设定自动缩进

设定

:set autoindent

:set ai

取消

:set noai

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

显示

:set hlsearch

取消

:set nohlsearch

19.7.5 语法高亮

高亮

:syntax on

取消

:syntax off

19.8 配置文件

/etc/vimrc

~/.vimrc

18、bash脚本编程之四 字符串测试,组合测试及for循环

练习:

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

18.1 字符(串)测试:

    ==:测试是否相等,相等为真,不等为假(等号两端必须要加空格)

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

    >:测试一个字符串是否大于另外一个字符串

    <:测试一个字符串是否小于另外一个字符串

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

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

    [root@Daniel-R480 ~]# A=hello

    [root@Daniel-R480 ~]# B=hi

    [root@Daniel-R480 ~]# [ “$A”==”B” ]

    [root@Daniel-R480 ~]# echo $?

    0

    [root@Daniel-R480 ~]# [ “$A” == “B” ]

    [root@Daniel-R480 ~]# echo $?

    1

    [root@Daniel-R480 ~]# [ “$A” = “$B” ]

    [root@Daniel-R480 ~]# echo $?

    1

    #‘’代表着直接对比A和B

    [root@Daniel-R480 ~]# [ ‘$A’ = ‘$B’ ]

    [root@Daniel-R480 ~]# echo $?

    1

    [root@Daniel-R480 ~]# [ “$A” = “$B” ]

    [root@Daniel-R480 ~]# echo $?

    1

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# [ “$A” != “$B” ]

    [root@Daniel-R480 ~]# echo $?

    0

    [root@Daniel-R480 ~]#

练习:写一个脚本

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

练习:写一个脚本

    传递一个参数(单字符就行)给脚本,如参数为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

18.2 组合测试条件

    -a: 与关系

    -o: 或关系

    !: 非关系

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

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

    q, Q, quit, Quit

练习:

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

./calc.sh 5 / 2

练习:

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

写一个脚本:

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

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

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

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

写一个脚本:

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

MAX=0

MAX -eq $1

MAX=$1

MAX -lt $2

MAX=$2

18.3 for循环

    循环:进入条件,退出条件

    for

    while

    until

    for 变量 in 列表; do

      循环体

    done

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

      加法运算

    done

    遍历完成之后,退出;

如何生成列表:

(1){1..100}:直接通过数字列表

(2)`seq [起始数 [步进长度]] 结束数`:通过seq命令

    [root@Daniel-R480 ~]# seq 3

    1

    2

    3

    [root@Daniel-R480 ~]# seq 5 10

    5

    6

    7

    8

    9

    10

    [root@Daniel-R480 ~]# seq 2 2 10

    2

    4

    6

    8

    10

    [root@Daniel-R480 ~]#

    #!/bin/bash

    #

    declare -i SUM=0

    for I in {1..100};do

        let SUM=$[$SUM+$I]

    done

    echo “The sum is : $SUM”

    1,…,100

    declare -i SUM=0

        integer

        -x

写一个脚本:

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

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

    Hello, root, your shell: /bin/bash

    [root@Daniel-R480 ~]# for I in `seq 1 $LINES`; do echo “Hello, `head -n $I /etc/passwd | tail -1 | cut -d: -f1`”; done

    Hello, root

    Hello, bin

    Hello, daemon

    Hello, adm

    Hello, lp

    Hello, sync

    Hello, shutdown

    Hello, halt

    Hello, mail

    Hello, operator

    Hello, games

    Hello, ftp

    Hello, nobody

    Hello, systemd-network

    Hello, dbus

    Hello, polkitd

    Hello, rpc

    Hello, rpcuser

    Hello, nfsnobody

    Hello, sshd

    Hello, postfix

    Hello, chrony

    Hello, daniel

    Hello, daniel

    Hello, daniel

    Hello, daniel

    Hello, daniel

    Hello, daniel

    Hello, daniel

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

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

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

写一个脚本:

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

    #!/bin/bash

    #

    for I in {1..10};do

            if id user$I &>/dev/null; then

               echo “user$I exists.”

            else

               useradd user$I

               echo user$I | passwd –stdin user$I &> /dev/null

            fi

    done

    #!/bin/bash

    #

    for I in {1..10}; do

            if id user$I &>/dev/null; then

              userdel -r user$I

              echo “Delete user$I finished.”

            else

              echo “user$I not exist.”

            fi

    done

扩展:

接受一个参数:

add: 添加用户user1..user10

del: 删除用户user1..user10

其它:退出

    #!/bin/bash

    #

    if [ $# -lt 1 ];then

            echo “Usage; adminusers –ARG”

            exit 7

    fi

    if [ $1 == ‘–add’ ];then

      for I in {1..10}; do

            if id user$I &> /dev/null; then

              echo “user$I exists.”

            else

              useradd user$I

              echo user$I | passwd –stdin user$I &> /dev/null

              echo “Add user$I finished.”

            fi

       done

    elif [ $1 == ‘–del’ ]; then

       for I in {1..10};do

         if id user$I &> /dev/null;then

          userdel -r user$I

          echo “Delete user$I finished.”

         else

          echo “No user$I.”

         fi

       done

    else

       echo “Unknown ARG”

       exit 8

    fi

设置adminusers user1,user2,user3,hello,hi

    #!/bin/bash

    #

    if [ $1 == ‘–add’ ]; then

      for I in `echo $2 | sed ‘s/,/ /g’`;do

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

          echo “$I exists.”

        else

          useradd $I

          echo $I | passwd –stdin $I &> /dev/null

          echo “add $I finished.”

         fi

       done

    elif [ $1 == ‘–del’ ]; then

      for I in `echo $2 | sed ‘s/,/ /g’`;do

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

            userdel -r $I

            echo “Delete $I finished.”

        else

            echo “$I NOT exist.”

        fi

      done

    elif [ $1 == ‘–help’ ]; then

       echo “Usage:adminuser2.sh –add USER1,USER2,… | –del USER1,USER@@,…”

    else

      echo “Unknown options.”

    fi

写一个脚本:

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

取模,取余:%

3%2=1

100%55=45

写一个脚本:

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

18.4 let命令和数据计算

    let命令

    let I=$[$I+1]

    SUM=$[$SUM+$I]和let SUM+=$I是一个意思

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

    [root@Daniel-R480 ~]# I=3

    [root@Daniel-R480 ~]# let I++

    [root@Daniel-R480 ~]# echo $I

    4

    [root@Daniel-R480 ~]# let I++

    [root@Daniel-R480 ~]# echo $I

    5

    -=:表示=-相对应的数值

    let I-=1 相当于 let I–

    ++I, –I

    *=:表示=*相对应的数值

    /=:表示=/相对应的数值

    %=:表示=%(取余)相对应的数值

写一个脚本,

分别显示当前系统上所有默认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

17、Sed命令及其用法

grep, sed(流编辑器/数据流编辑器), awk(报告文本生成器)    

17.1 sed基本用法:

sed: Stream Editor

    行编辑器 (全屏编辑器: vi)

sed: 模式空间

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

sed [options] ‘AddressCommand’ file …

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

    -i: 直接修改原文件

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

               添加脚本到被执行的命令当中

    -f /PATH/TO/SED_SCRIPT

        sed -f /path/to/scripts  file

        添加脚本的内容到被执行的命令当中

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

17.2 Address制定方法:

1、StartLine,EndLine(起始行到结束行)

    比如1,100:第一行开始到第100行结束

    $:最后一行

    $-1:倒数第二行

2、/RegExp/(使用正则表达式来指定模式)

    /^root/

3、/pattern1/,/pattern2/

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

4、LineNumber

    指定的行(指定精确某一行)

5、StartLine, +N

    从startLine开始,向后的N行,总共是N+1行

17.3 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: like–>liker

          love–>lover

          like–>Like

          love–>Love

    &: 引用模式匹配到的整个字符串

sed练习:

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

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

[root@Daniel-R480 ~]# cat /etc/grub.conf

default=0

timeout=0

title CentOS Linux 7 (3.10.0-957.1.3.el7.x86_64)

        root (hd0)

        kernel /boot/vmlinuz-3.10.0-957.1.3.el7.x86_64 ro root=UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d console=hvc0 LANG=en_US.UTF-8

        initrd /boot/initramfs-3.10.0-957.1.3.el7.x86_64.img

[root@Daniel-R480 ~]# sed -r ‘s@^[[:space:]]+@@g’ /etc/grub.conf

default=0

timeout=0

title CentOS Linux 7 (3.10.0-957.1.3.el7.x86_64)

root (hd0)

kernel /boot/vmlinuz-3.10.0-957.1.3.el7.x86_64 ro root=UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d console=hvc0 LANG=en_US.UTF-8

initrd /boot/initramfs-3.10.0-957.1.3.el7.x86_64.img

[root@Daniel-R480 ~]#

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

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

[root@Daniel-R480 ~]# cat /etc/inittab

# inittab is no longer used when using systemd.

#

# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

#

# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target

#

# systemd uses ‘targets’ instead of runlevels. By default, there are two main targets:

id:3:initdefault:

#

# multi-user.target: analogous to runlevel 3

# graphical.target: analogous to runlevel 5

#

# To view current default target, run:

# systemctl get-default

#

# To set a default target, run:

# systemctl set-default TARGET.target

#

[root@Daniel-R480 ~]# sed ‘s@\(id:\)[0-9]\(:initdefault:\)@\15\2@g’ /etc/inittab

# inittab is no longer used when using systemd.

#

# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

#

# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target

#

# systemd uses ‘targets’ instead of runlevels. By default, there are two main targets:

id:5:initdefault:

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

sed ‘/^$/d’ /etc/inittab

[root@Daniel-R480 ~]# cat !$

cat /etc/inittab

# inittab is no longer used when using systemd.

#

# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

#

# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target

#

# systemd uses ‘targets’ instead of runlevels. By default, there are two main targets:

id:3:initdefault:

#

# multi-user.target: analogous to runlevel 3

# graphical.target: analogous to runlevel 5

#

# To view current default target, run:

# systemctl get-default

#

# To set a default target, run:

# systemctl set-default TARGET.target

#

[root@Daniel-R480 ~]#

[root@Daniel-R480 ~]#

[root@Daniel-R480 ~]# sed ‘/^$/d’ /etc/inittab

# inittab is no longer used when using systemd.

#

# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

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

sed ‘s@^#@@g’ /etc/inittab

[root@Daniel-R480 ~]# sed ‘s@^#@@g’ /etc/inittab

 inittab is no longer used when using systemd.

 ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

 Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target

 systemd uses ‘targets’ instead of runlevels. By default, there are two main targets:

id:3:initdefault:

 multi-user.target: analogous to runlevel 3

 graphical.target: analogous to runlevel 5

 To view current default target, run:

 systemctl get-default

 To set a default target, run:

 systemctl set-default TARGET.target

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

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

[root@Daniel-R480 ~]# sed -r ‘s@^#[[:space:]]+@@g’ /etc/inittab

inittab is no longer used when using systemd.

#

ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

#

Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target

#

systemd uses ‘targets’ instead of runlevels. By default, there are two main targets:

id:3:initdefault:

#

multi-user.target: analogous to runlevel 3

graphical.target: analogous to runlevel 5

#

To view current default target, run:

systemctl get-default

#

To set a default target, run:

systemctl set-default TARGET.target

#

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

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

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

echo “/etc/rc.d/” | sed -r ‘s@^(/.*/)[^/]+/?@\1@g’  

基名:

echo “/etc/rc.d/” | sed -r ‘s@^/.*/([^/]+)/?@\1@g’  

#abc

# hello world

   # hi world

16、bash脚本编程之三 整数测试及特殊变量

16.1 算术运算方法

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`

16.2 测试方法:

[ expression ]

[[ expression ]]

test expression

bash中常用的条件测试有三种:

16.2.1 整数测试:

        -gt:大于

        -le:小于等于

        -ne:不等于

        -eq:等于

        -ge

        -lt

测试两个整数(只有进行整数测试时才能用[],其他情况一定不能加)

INT1=63

INT2=77

[ $INT1 -eq $INI2 ]

[[ $INT1 -eq $INT2 ]]

test $INT1 -eq $INT2  

16.2.2 文件测试: 

-e FILE:测试文件是否存在

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

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

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

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

-x FILE: 测试当前用户对指定文件是否有执行权限;

例:

[ -e /etc/inittab ]

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

练习:写一个脚本

给定一个文件:

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

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

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

16.3 定义脚本退出状态码

exit: 退出脚本

exit #

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

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

bash -n 脚本(不能作为判断依据,只能用来参考)

bash -x 脚本:单步执行

16.4 bash变量的类型:

        (1)本地变量(局部变量)

        (2)环境变量

        (3)位置变量: 

                $1, $2, …(表示脚本的第n个参数)

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

                $1: /etc/fstab

                $2: /etc/inittab

                shift:轮换轮替

                [daniel@localhost tmp]$ vim shift.sh

                [daniel@localhost tmp]$ chmod +x shift.sh 

                [daniel@localhost tmp]$ ./shift.sh 

                [daniel@localhost tmp]$ ./shift.sh 1 2 3

                1

                2

                3

                [daniel@localhost tmp]$ help shift

                shift: shift [n]

                    Shift positional parameters.

                    Rename the positional parameters $N+1,$N+2 … to $1,$2 …  If N is

                    not given, it is assumed to be 1.

                    Exit Status:

                    Returns success unless N is negative or greater than $#.

                #!/bin/bash

                #

                echo $1

                shift

                echo $1

                shift

                echo $1

       (4)特殊变量:

                $?:上一条命令的退出状态码

                $#:参数的个数

                $*: 参数列表

                $@:参数列表

练习1:写一脚本

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

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

练习:写一个脚本

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

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

#!/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].”

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

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

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

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

练习3:写一个脚本

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

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

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

#!/bin/bash

#grep “^$” /etc/inittab &> /dev/null

#TEST=$?

#if [ $TEST -eq 0 ];then

#    echo `grep “^$” /etc/inittab | wc -l`

#else

#    echo ” no blank lines”

#fi

###张帅

#!/bin/bash

#A=`grep ‘^$’ /etc/inittab | wc -l`

#if [ $A -gt 0 ]; then

# echo “$A”

#else

# echo “meiyoukongbaihang”

#fi

#脚本执行过程比较浪费,效率比较低,所以使用exit直接退出脚本

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

练习4:写一个脚本

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

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

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

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

exit:退出脚本(用于定义执行状态及其结果)

exit +数值(0-255)0为正确,其他为错误

练习5:写一个脚本

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

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

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

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

圆整:丢弃小数点后的所有内容(bash默认使用此种方式进行计算)

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

15、bash脚本编程之二 条件判断及算术运算

15.1 条件判断:

        如果用户不存在

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

        否则

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

条件判断,控制结构:

1、单分支if语句

        if 判断条件; then

                statement1

                statement2

                …

        fi

        双分支的if语句:

        if 判断条件; then

                statement1

                statement2

                …

        else

                statement3

                statement4

                …

        fi

2、多分支的if语句:

        if 判断条件1; then

                statement1

                …

        elif 判断条件2; then

                statement2

                …

        elif 判断条件3; then

                statement3

                …

        else

                statement4

                …

        fi

15.2 bash中如何实现条件判断?

1、实现方法:

        1、查看状态返回值

2、条件测试类型:

        1、整数测试:判断整数是否正确

        2、字符测试

        3、文件测试

3、条件测试的表达式:

        1、[ expression ]

        2、[[ expression ]]

        3、test expression

4、整数比较:

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

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

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

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

        -ge: 大于或等于

        -le:小于或等于

        [root@Daniel-R480 ~]# A=3

        [root@Daniel-R480 ~]# B=6

        [root@Daniel-R480 ~]# [$A -eq $B]

        -bash: [3: command not found

        [root@Daniel-R480 ~]# [ $A -eq $B]

        -bash: [: missing `]’

        [root@Daniel-R480 ~]# [ $A -eq $B ]

        [root@Daniel-R480 ~]# echo $?

        1

        [root@Daniel-R480 ~]# [ $A -ne $B ]

        [root@Daniel-R480 ~]# echo $?

        0

        [root@Daniel-R480 ~]# [ $A -gt $B ]

        [root@Daniel-R480 ~]# echo $?

        1

        [root@Daniel-R480 ~]# [ $A -lt $B ]

        [root@Daniel-R480 ~]# echo $?

        0

        [root@Daniel-R480 ~]# [ $A -ge $B ]

        [root@Daniel-R480 ~]# echo $?

        1

        [root@Daniel-R480 ~]# [ $A -le $B ]

        [root@Daniel-R480 ~]# echo $?

        0

        [root@Daniel-R480 ~]#

5、命令的间逻辑关系:

        (1)逻辑与: &&

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

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

                [root@Daniel-R480 ~]# id user1 &>/dev/null && echo “hello student”

                hello student

                [root@Daniel-R480 ~]# id user3 &>/dev/null && echo “hello student”

                [root@Daniel-R480 ~]# useradd user3

                [root@Daniel-R480 ~]# id user3 &>/dev/null && echo “hello student”

                hello student

                [root@Daniel-R480 ~]#

        (2)逻辑或: ||

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

        ! id user6 && useradd user6

        id user6 || useradd user6

        [root@Daniel-R480 ~]# id user6 || useradd user6

        id: user6: no such user

        [root@Daniel-R480 ~]# id user6 || useradd user6

        uid=10019(user6) gid=10019(user6) groups=10019(user6)

        [root@Daniel-R480 ~]# id user6 || useradd user6

        uid=10019(user6) gid=10019(user6) groups=10019(user6)

        [root@Daniel-R480 ~]# id user6 &>/dev/null || useradd user6

        [root@DanielR480 ~]# (id user6 &>/dev/null || useradd user6)&& echo ‘hello user6’

        hello user6

        [root@Daniel-R480 ~]#

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

[ `wc -l /etc/inittab | cut -d’ ‘ -f1` -gt 100 ] && echo “Large file.”

6、变量名称定义规范:

        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.”

练习,写一个脚本,完成以下要求:

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

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

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

练习,写一个脚本,完成以下要求:

给定一个用户:

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

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

如果其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

        if id $NAME; then

练习:写一个脚本

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

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

        #!/bin/bash

        #grep “bash$” /etc/passwd &> /dev/null

        grep “xsh$” /etc/passwd &> /dev/null

        RETVAL=$?

        if [ $RETVAL -eq 0 ];then

        #COUNT=`grep “bash$” /etc/passwd | wc -l`

        #echo $COUNT

        echo `grep “bash$” /etc/passwd | wc -l`

        else

        echo “There is no such users.”

        fi

        不能如此执行: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`;

练习:写一个脚本

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

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

        #!/bin/bash

        grep “bash$” /etc/passwd &> /dev/null

        #grep “xsh$” /etc/passwd &> /dev/null

        RETVAL=$?

        if [ $RETVAL -eq 0 ];then

        #COUNT=`grep “bash$” /etc/passwd | wc -l`

        #echo $COUNT

        #echo `grep “bash$” /etc/passwd | wc -l`

        echo `grep “bash$” /etc/passwd | head -1 | cut -d’:’ -f1`

        else

        echo “There is no such users.”

        fi

        fi

14、bash脚本编程之一,变量和变量类型

14.1 shell编程:脚本编程基础

    编译器,解释器:将汇编语言或者是高级语言转换为机器语言的翻译设备或软件

    编程语言:机器语言、汇编语言、高级语言(符合人类的思考模式,而且能通过编译器转换为机器语言)

14.1.1 编程语言分类

    1、高级语言分类

        (1)静态语言:编译型语言

            强类型(变量类型)

            事先转换成可执行格式(不需要解释器就能执行)

            C、C++、JAVA、C#

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

            弱类型语言

            边解释边执行(必须要解释器才能正常执行)

            PHP、SHELL、python、perl

    2、根据执行情况分类

        面向过程(着眼点再解决问题本身):Shell, C

        面向对象(着眼点在于一个一个的对象): JAVA, Python, perl, C++

        变量:内存空间,命名,可以不断地更新内容

        内存:编址的存储单元

        进程:将数据临时放于内存当中

            1+100:

            1+1000000

            1

14.1.2 bash: 

    1、保存类型:

        (1)字符

        (2)数值

            (a)整型

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

            2013/10/10, 存为字符串格式需要64bit

            99999: 存为数字格式需要24bit, 

        (3)真、假

            整型,8bit,保存256的话会发生溢出,导致部分程序运行不正常,称之为是缓冲区溢出

            逻辑运算

            逻辑:1+1>2

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

                1: 真

                0: 假

        与

            1 & 0  = 0

            0 & 1 = 0

            0 & 0 = 0

            1 & 1 = 1

        或:

        非:

            ! 真 = 假

            ! 假 = 真

        异或

            操作数相同为假,不同则为真

14.2 变量及变量操作

        shell: 弱类型编程语言

14.2.1 变量类型:

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

    弱:变量用时声明,甚至不区分类型;(一般默认为字符串)

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

    变量赋值:VAR_NAME=VALUE

1、bash变量类型:

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

        export VARNAME=VALUE

        VARNAME=VALUE

        export VARNAME

            “导出”

    本地变量(局部变量):set VARNAME=VALUE: 作用域为整个bash进程;(set可省略)

    引用变量:${VARNAME} (会造成混淆时使用{}),{}有时可省略

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

    位置变量:$1, $2, …

    特殊变量(系统变量):用于保存一些特殊数据

        $?: 上一个命令的执行状态返回值;

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

        (1)程序执行结果

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

            0: 正确执行

            1-255:错误执行,1,2,127系统预留;其他的返回值可以自己定义

    [root@Daniel-R480 ~]# clear

    [root@Daniel-R480 ~]# echo $?

    0

    [root@Daniel-R480 ~]# ll

    total 16

    -rw——- 1 root   root 6921 Jan 29  2019 anaconda-ks.cfg

    -rw-r–r– 1 root   root    0 Jun  7 10:55 cut

    -rw-r–r– 1 root   root    0 Jun  7 09:47 hellosa

    -rwx—— 1 apache root  513 Jun  4 11:52 inittab

    -rw——- 1 root   root 6577 Jan 29  2019 original-ks.cfg

    -rw-r–r– 1 root   root   15 Jun  7 10:53 passwd.txt

    -rw-r–r– 1 root   root   91 Jun  7 13:43 test2.txt

    -rw-r–r– 1 root   root   12 Jun  7 14:43 test3.txt

    -rw-r–r– 1 root   root   46 Jun  7 11:49 test.txt

    [root@Daniel-R480 ~]# echo $?

    0

    [root@Daniel-R480 ~]# ld

    ld: no input files

    [root@Daniel-R480 ~]# echo $?

    1

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# id student &> /dev/null

    [root@Daniel-R480 ~]# echo $?

    1

    dev/null: 软件设备(模拟的不存在的设备), bit bucket,数据黑洞(会吞掉所有接受到的数据) 

    echo $?,可用来判断用户是否存在

    输出重定向:

        >,>>,2>,2>>,&>

    撤消变量:

        unset VARNAME

    查看当shell中变量:

        set

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

        printenv

        env

        export

    [root@Daniel-R480 ~]# ANIMALS=PIG

    [root@Daniel-R480 ~]# ANIMALS=$ANIMALS:GOAT

    [root@Daniel-R480 ~]# echo $ANIMALS

    PIG:GOAT

    [root@Daniel-R480 ~]# ANIMALS=$ANIMALS:SHEEP

    [root@Daniel-R480 ~]# echo $ANIMALS

    PIG:GOAT:SHEEP

    shell默认不进行数据的运算

14.3 BASH脚本

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

1、shebang: 魔数(每个脚本的第一行)

    #!/bin/bash(#!+脚本的解释路径)

    # 注释行,不执行(正文里面的#作用)

    [root@Daniel-R480 ~]# vim first.sh

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# file /bin/ls

    /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=ceaf496f3aec08afced234f4f36330d3d13a657b, stripped

    [root@Daniel-R480 ~]# file first.sh

    first.sh: ASCII text

    [root@Daniel-R480 ~]# vim first.sh

    [root@Daniel-R480 ~]# file first.sh

    first.sh: Bourne-Again shell script, ASCII text executable

    [root@Daniel-R480 ~]# ll first.sh

    -rw-r–r– 1 root root 35 Jun  7 17:44 first.sh

    [root@Daniel-R480 ~]# chmod +x first.sh

    [root@Daniel-R480 ~]# ./first.sh

    #

    # /etc/fstab

    # Created by anaconda on Mon Jan 28 20:51:49 2019

    #

    # Accessible filesystems, by reference, are maintained under ‘/dev/disk’

    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

    #

    UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d /                       xfs     defaults        0 0

    adm    crash  empty  gopher    lib    lock  mail  opt       run    tmp      yp

    cache  db     games  kerberos  local  log   nis   preserve  spool  var.out

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# chmod -x first.sh

    [root@Daniel-R480 ~]# ll

    total 16

    -rw——- 1 root   root 6921 Jan 29  2019 anaconda-ks.cfg

    -rw-r–r– 1 root   root    0 Jun  7 10:55 cut

    -rw-r–r– 1 root   root   35 Jun  7 17:44 first.sh

    -rw-r–r– 1 root   root    0 Jun  7 09:47 hellosa

    -rwx—— 1 apache root  513 Jun  4 11:52 inittab

    -rw——- 1 root   root 6577 Jan 29  2019 original-ks.cfg

    -rw-r–r– 1 root   root   15 Jun  7 10:53 passwd.txt

    -rw-r–r– 1 root   root   91 Jun  7 13:43 test2.txt

    -rw-r–r– 1 root   root   12 Jun  7 14:43 test3.txt

    -rw-r–r– 1 root   root   46 Jun  7 11:49 test.txt

    [root@Daniel-R480 ~]# bash first.sh

    #

    # /etc/fstab

    # Created by anaconda on Mon Jan 28 20:51:49 2019

    #

    # Accessible filesystems, by reference, are maintained under ‘/dev/disk’

    # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

    #

    UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d /                       xfs     defaults        0 0

    adm    crash  empty  gopher    lib    lock  mail  opt       run    tmp      yp

    cache  db     games  kerberos  local  log   nis   preserve  spool  var.out

    [root@Daniel-R480 ~]#

2、脚本和环境关系

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

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

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

练习:

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

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

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

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

    #!/bin/bash

    #

    useradd user1

    echo !$ | passwd –stdin &>/dev/null

    echo “Add user1 successfully!”

    useradd user2

    echo !$ | passwd –stdin &>/dev/null

    echo “Add user2 successfully!”

    useradd user3

    echo !$ | passwd –stdin &>/dev/null

    echo “Add user3 successfully!”

    useradd user4

    echo !$ | passwd –stdin &>/dev/null

    echo “Add user4 successfully!”

    useradd user5

    echo !$ | passwd –stdin &>/dev/null

    echo “Add user5 successfully!”

    [root@Daniel-R480 ~]# ./aduser.sh

        Add user1 successfully!

        Add user2 successfully!

        Add user3 successfully!

        Add user4 successfully!

        Add user5 successfully!

        [root@Daniel-R480 ~]# tail -5 /etc/passwd

        user1:x:4008:4008::/home/user1:/bin/bash

        user2:x:4009:4009::/home/user2:/bin/bash

        user3:x:4010:4010::/home/user3:/bin/bash

        user4:x:4011:4011::/home/user4:/bin/bash

        user5:x:4012:4012::/home/user5:/bin/bash

    [root@Daniel-R480 ~]#

13、egrep和扩展的正则表达式

13.1 grep

    REGEXP:REGular EXPression(正则表达式)

    Pattern: (模式)

    1、正则表达式:

        Basic REGEXP:基本

        Extended REGEXP:扩展

    2、基本正则表达式:

        .: 任意词

        []: 括号中间的任意单个字符

        [^]:反向选取

    3、次数匹配:

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

        \?: 0或1次

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

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

    4、锚定:

        ^:行首

        $:行尾

        \<, \b:单词首

        \>, \b:单词尾

        \(\):用于实现分组引用

            \1, \2, \3, …(引用前面第n个小括号里面的内容)

    grep:使用基本正则表达式定义的模式来过滤文本的命令(默认只支持基本正则表达式);

        -i:忽略大小写

        -v:反向搜索

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

        –color:显示颜色

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

        -A #: 显示匹配到的某一行后面的第n行

        -B #: 显示匹配到的某一行前面的第n行

        -C #:显示匹配到的某一行前后面各n行

    [root@Daniel-R480 ~]# grep -A 2 ‘^core id’ /proc/cpuinfo

    core id         : 0

    cpu cores       : 4

    apicid          : 0

    [root@Daniel-R480 ~]# grep -B 2 ‘^core id’ /proc/cpuinfo

    physical id     : 0

    siblings        : 8

    core id         : 0

    [root@Daniel-R480 ~]# grep -C 2 ‘^core id’ /proc/cpuinfo

    physical id     : 0

    siblings        : 8

    core id         : 0

    cpu cores       : 4

    apicid          : 0

    —

13.2 扩展正则表达式:

    字符前面默认不加\

    1、字符匹配:

        .

        []

        [^]

    2、次数匹配:

        *: 

        ?:

        +: 匹配其前面的字符至少1次

        {m,n}

    3、位置锚定:

        ^

        $

        \<

        \>

    4、分组:

        ():分组

        \1, \2, \3, …

    5、或者

        |: or

        C|cat: C或cat(匹配的是C或者cat,匹配左边或者右边的内容)

        (C|c)at:Cat或者cat

    [root@Daniel-R480 ~]# grep -E –color ‘C|cat’ test3.txt

    cat

    Cat

    C

    [root@Daniel-R480 ~]# grep -E ‘C|cat’ test3.txt

    cat

    Cat

    C

    [root@Daniel-R480 ~]# grep -E ‘(C|c)at’ test3.txt

    cat

    Cat

    [root@Daniel-R480 ~]# cat ./test3.txt

    cat

    Cat

    C

    c

    [root@Daniel-R480 ~]#

grep -E = egrep 

练习

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

        ls *[^[:space:]]*[0-9]   ?????????

        \.让元字符表示它本身的意义

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

    [root@Daniel-R480 ~]# egrep ‘\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>’ /boot/grub/grub.conf

    title CentOS Linux 7 (3.10.0-957.1.3.el7.x86_64)

            kernel /boot/vmlinuz-3.10.0-957.1.3.el7.x86_64 ro root=UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d console=hvc0 LANG=en_US.UTF-8

            initrd /boot/initramfs-3.10.0-957.1.3.el7.x86_64.img

    [root@Daniel-R480 ~]# 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])\>’

            inet 192.168.18.116  netmask 255.255.255.0  broadcast 192.168.18.255

            inet www.danios.com  netmask 255.0.0.0

    [root@Daniel-R480 ~]# 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])\>’

            inet 192.168.18.116  netmask 255.255.255.0  broadcast 192.168.18.255

            inet www.danios.com  netmask 255.0.0.0

    [root@Daniel-R480 ~]# ifconfig |  egrep ‘\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>’

            inet 192.168.18.116  netmask 255.255.255.0  broadcast 192.168.18.255

            ether e8:6a:64:86:12:9f  (Ethernet)

    lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 1500

            inet www.danios.com  netmask 255.0.0.0

            inet6 ::1  prefixlen 128  scopeid 0xfe<compat,link,site,host>

    [root@Daniel-R480 ~]# ifconfig | egrep –color -o ‘(\<([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])\>’

    192.168.18.116

    255.255.255.0

    192.168.18.255

    www.danios.com

    255.0.0.0

    2、只输出ifconfig里面的ip地址

        IPv4: 

            5类:A B C D E

            A:1-127

            B:128-191

            C:192-223

    只显示ip地址

    [root@Daniel-R480 ~]# ifconfig | egrep ‘\<([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])\>’

            inet 192.168.18.116  netmask 255.255.255.0  broadcast 192.168.18.255

            inet www.danios.com  netmask 255.0.0.0

    [root@Daniel-R480 ~]# ifconfig | egrep -o ‘\<([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])\>’

    192.168.18.116

    www.danios.com

    [root@Daniel-R480 ~]#

12、grep及正则表达式

12.1 grep

    egrep:扩展正则表达式

    fgrep(快速的搜索): 不支持正则表达式,直接搜索字符本身

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

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

    grep [options] PATTERN [FILE…]

        -i:忽略字母大小写

        –color:对于被选中的目标用颜色显示

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

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

12.2 正则表达式(REGular EXPerssion,REGEXP)

    通常使用的匹配的字符

    *: 匹配任意长度的任意字符

    ?: 任意单个字符

    []:指定范围内的内容

    [^]:制定范围外的内容

12.2.1 正则表达式的元字符:

    1、元字符

        .  : 匹配任意单个字符

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

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

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

    [root@Daniel-R480 ~]# grep ‘r..t’ /etc/passwd

    root:x:0:0:root:/root:/bin/bash

    operator:x:11:0:operator:/root:/sbin/nologin

    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

    [root@Daniel-R480 ~]#

    2、匹配次数(贪婪模式,尽可能多的匹配):

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

        a, b, ab, aab, acb, adb, amnb

        a*b:a出现任意次之后跟着b 

    [root@Daniel-R480 ~]# grep ‘a*b’ test.txt

    b

    ab

    asb

    aab

    abb

    ammjdjfdjb

    asdbsdabsfdab

    a?b:匹配a任意次,然后加上b

    [root@Daniel-R480 ~]# grep ‘a\?b’ test.txt

    b

    ab

    asb

    aab

    abb

    ammjdjfdjb

    asdbsdabsfdab

    a.*b:a开头,b结尾,中间跟任意字符

    [root@Daniel-R480 ~]# grep ‘a.*b’ test.txt

    ab

    asb

    aab

    abb

    ammjdjfdjb

    asdbsdabsfdab

    3、匹配规则

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

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

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

            \{1,\}

            \{0,3\}

    [root@Daniel-R480 ~]# grep ‘a\{1,3\}b’ test.txt

    ab

    aab

    abb

    asdbsdabsfdab

    [root@Daniel-R480 ~]# grep ‘a.\{1,3\}b’ test.txt

    asb

    aab

    abb

    asdbsdabsfdab

    [root@Daniel-R480 ~]#

    4、位置锚定:

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

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

        ^$: 空白行

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

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

    [root@Daniel-R480 ~]# grep ‘r..t’ /etc/passwd

    root:x:0:0:root:/root:/bin/bash

    operator:x:11:0:operator:/root:/sbin/nologin

    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

    [root@Daniel-R480 ~]# grep ‘&r..t’ /etc/passwd

    [root@Daniel-R480 ~]# grep ‘^r..t’ /etc/passwd

    root:x:0:0:root:/root:/bin/bash

    [root@Daniel-R480 tmp]# grep “root\>” ./test.txt

    This is root

    the user is mroot

    chroot is a command

    [root@Daniel-R480 tmp]# grep “\>root” ./test.txt

    [root@Daniel-R480 tmp]# grep “root\>” ./test.txt

    This is root

    the user is mroot

    chroot is a command

    [root@Daniel-R480 tmp]# grep “\<root” ./test.txt

    This is root

    rooter is a dog’s name

    [root@Daniel-R480 tmp]# grep “\<root\>” ./test.txt

    This is root

    [root@Daniel-R480 tmp]#

    5、分组:

    \(\):把内容分组

        \(ab\)*:ab可以出现任意次

        [root@Daniel-R480 ~]# cat test.txt

        a

        b

        ab

        asb

        aab

        abb

        ammjdjfdjb

        asdbsdabsfdab

        [root@Daniel-R480 ~]# grep “\(ab\)*” test.txt

        a

        b

        ab

        asb

        aab

        abb

        ammjdjfdjb

        asdbsdabsfdab

        [root@Daniel-R480 ~]# grep “\(ab\)\?” test.txt

        a

        b

        ab

        asb

        aab

        abb

        ammjdjfdjb

        asdbsdabsfdab

        [root@Daniel-R480 ~]#

    6、后向引用(被前面括号括起来的字符,可以在后面继续引用他)

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

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

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

    He love his lover.

    She like her liker.

    He like his lover.

    [root@Daniel-R480 ~]# vim test2.txt

    [root@Daniel-R480 ~]# grep ‘l..e’ test2.txt

    He love his lover.

    She like her liker.

    He like his lover.

    She love her liker.

    [root@Daniel-R480 ~]# grep ‘l..e.*l..e’ test2.txt

    He love his lover.

    She like her liker.

    He like his lover.

    She love her liker.

    [root@Daniel-R480 ~]# vim test2.txt

    [root@Daniel-R480 ~]# grep ‘l..e.*l..e’ test2.txt

    He love his lover.

    She like her liker.

    He like his lover.

    She love her liker

    [root@Daniel-R480 ~]# grep ‘l..e.*\1’ test2.txt

    grep: Invalid back reference

    [root@Daniel-R480 ~]# grep ‘\(l..e\).*\1’ test2.txt

    He love his lover.

    She like her liker.

    l..e:l开头,e结尾

练习:

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

        [root@Daniel-R480 ~]# grep -i ‘^s’ /proc/meminfo

        SwapCached:            0 kB

        SwapTotal:      31018612 kB

        SwapFree:       31018612 kB

        Shmem:             17720 kB

        Slab:              13868 kB

        SReclaimable:       6744 kB

        SUnreclaim:         7124 kB

        [root@Daniel-R480 ~]# grep ‘^[sS]’ /proc/meminfo

        SwapCached:            0 kB

        SwapTotal:      31018612 kB

        SwapFree:       31018612 kB

        Shmem:             17720 kB

        Slab:              13868 kB

        SReclaimable:       6744 kB

        SUnreclaim:         7124 kB

        [root@Daniel-R480 ~]#

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

        [root@Daniel-R480 ~]# grep ‘nologin$’ /etc/passwd

        bin:x:1:1:bin:/bin:/sbin/nologin

        daemon:x:2:2:daemon:/sbin:/sbin/nologin

        adm:x:3:4:adm:/var/adm:/sbin/nologin

        lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

        mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

        operator:x:11:0:operator:/root:/sbin/nologin

        games:x:12:100:games:/usr/games:/sbin/nologin

        ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

        nobody:x:99:99:Nobody:/:/sbin/nologin

        systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin

        dbus:x:81:81:System message bus:/:/sbin/nologin

        polkitd:x:999:998:User for polkitd:/:/sbin/nologin

        rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin

        rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin

        nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

        sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

        postfix:x:89:89::/var/spool/postfix:/sbin/nologin

        chrony:x:998:995::/var/lib/chrony:/sbin/nologin

        test3:x:10014:10014::/home/test3:/sbin/nologin

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

        [root@Daniel-R480 ~]# grep ‘nologin$’ /etc/passwd | cut -d: -f1

        bin

        daemon

        adm

        lp

        mail

        operator

        games

        ftp

        nobody

        systemd-network

        dbus

        polkitd

        rpc

        rpcuser

        nfsnobody

        sshd

        postfix

        chrony

        test3

        [root@Daniel-R480 ~]#

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

        [root@Daniel-R480 ~]# grep ‘bash$’ /etc/passwd | sort -n -t: -k3 | head -1 | cut -d: -f1

        root

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

        [root@Daniel-R480 ~]# grep “^#[[:space:]]\{1,\}[^[:space:]]” /etc/inittab

        # inittab is no longer used when using systemd.

        # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.

        # Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target

        # systemd uses ‘targets’ instead of runlevels. By default, there are two main targets:

        # multi-user.target: analogous to runlevel 3

        # graphical.target: analogous to runlevel 5

        # To view current default target, run:

        # systemctl get-default

        # To set a default target, run:

        # systemctl set-default TARGET.target

        [root@Daniel-R480 ~]#

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

        [root@Daniel-R480 ~]# grep ‘^[[:space:]]\{1,\}’ /boot/grub/grub.conf

                root (hd0)

                kernel /boot/vmlinuz-3.10.0-957.1.3.el7.x86_64 ro root=UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d console=hvc0 LANG=en_US.UTF-8

                initrd /boot/initramfs-3.10.0-957.1.3.el7.x86_64.img

11、管道及I/O重定向

11.1 I/O以及I/O重定向

11.1.1 默认输入输出设备及程序运行流程简介

    管道和重定向:> < >> << 

    计算机5大部件:

        运算器、控制器: CPU

        存储器:RAM

        输入设备/输出设备

    程序:指令和数据(放于存储器中)

        控制器:读取指令,并读取需要的运算

        运算器:在控制器的控制线进行运算

        存储器:运算结果存储在存储器中

        三大总线:

            地址总线:内存寻址

            数据总线:传输数据

            控制总线:控制指令

    寄存器:CPU暂时存储器

    I/O设备(输入输出设备): 硬盘,键盘,鼠标

    程序运行时会使用默认的输入输出设备:INPUT设备,OUTPUT设备

    系统设定的默认输入输出设备

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

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

        标准错误输出:STDERR, 2

    对于计算机来说:

        标准输入:键盘

        标准输出和错误输出:显示器(因为廉价,可以输出无限的东西)

    passwd –stdin(获取标准输入为密码)

11.1.2 I/O重定向

    I/O重定向:将默认的输入输出来源改变为自己设定的内容

    [root@Daniel-R480 ~]# ls /var

    adm    crash  empty  gopher    lib    lock  mail  opt       run    tmp

    cache  db     games  kerberos  local  log   nis   preserve  spool  yp

    [root@Daniel-R480 ~]# ls /var >/var/var.out

    [root@Daniel-R480 ~]# vim /var/var.out

    [root@Daniel-R480 ~]# cat /var/var.out

    adm

    cache

    crash

    db

    empty

1、输出重定向

    Linux:

    (1)标准输出重定向

        >: 覆盖输出,覆盖原有的文件

        >>:追加输出

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

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

    set +C: 关闭上述功能

    (2)错误输出重定向

        2>: 重定向错误输出

        2>>: 追加方式

    [root@Daniel-R480 ~]# ls /varr > /tmp/var.out 2> /tmp/err.out

    [root@Daniel-R480 ~]# cat /tmp/err.out

    ls: cannot access /varr: No such file or directory

    [root@Daniel-R480 ~]#

    (3)标准和错误输出同时重定向

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

    [root@Daniel-R480 ~]# ls /varr &> /tmp/var.out

    [root@Daniel-R480 ~]# cat /tmp/var.out

    ls: cannot access /varr: No such file or directory

    [root@Daniel-R480 ~]#

2、输入重定向

    <:输入重定向

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

    [root@Daniel-R480 ~]# cat << END

    > 123

    > 234

    > END

    123

    234

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# cat << EOF

    > 123

    > EOF

    123

    [root@Daniel-R480 ~]# cat >> ‘./test.txt’ << EOF

    > 123

    > 234

    > EOF

    [root@Daniel-R480 ~]# cat ./test.txt

    123

    234

    [root@Daniel-R480 ~]#

3、管道

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

        命令1 | 命令2 | 命令3 | …

    tee :既显示输入的内容,又保存到文件中

    [root@Daniel-R480 ~]# echo “hello world”| tee /tmp/hello.out

    hello world

    [root@Daniel-R480 ~]# cat /tmp/hello.out

    hello world

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# wc -l /etc/passwd

    32 /etc/passwd

    [root@Daniel-R480 ~]# wc -l /etc/passwd | cut -d’ ‘ -f1

    32

    [root@Daniel-R480 ~]#

练习:

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

    # ls /usr/bin | wc -l

    [root@Daniel-R480 ~]# ls -l /usr/bin | wc -l

    790

    [root@Daniel-R480 ~]# ls -l /usr/bin | head -1

    total 64504

    [root@Daniel-R480 ~]# ls -l /usr/bin | head -2

    total 64504

    -rwxr-xr-x 1 root root     41544 Oct 31  2018 [

    [root@Daniel-R480 ~]# ls -l /usr/bin | head -3

    total 64504

    -rwxr-xr-x 1 root root     41544 Oct 31  2018 [

    -rwxr-xr-x 1 root root    107848 Feb  3 00:33 a2p

    [root@Daniel-R480 ~]# ls -l /usr/bin | head -4

    total 64504

    -rwxr-xr-x 1 root root     41544 Oct 31  2018 [

    -rwxr-xr-x 1 root root    107848 Feb  3 00:33 a2p

    -rwxr-xr-x 1 root root     29200 Oct 30  2018 addr2line

    [root@Daniel-R480 ~]# ls -lh /usr/bin | head -1

    total 64M

    [root@Daniel-R480 ~]#

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

    [root@Daniel-R480 ~]# cut -d: -f7 /etc/passwd | sort -u

    /bin/bash

    /bin/sh

    /bin/sync

    /sbin/halt

    /sbin/nologin

    /sbin/shutdown

    [root@Daniel-R480 ~]#

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

    [root@Daniel-R480 ~]# file /var/log/*

    /var/log/anaconda:           directory

    /var/log/audit:              directory

    /var/log/boot.log:           empty

    /var/log/btmp:               empty

    /var/log/chrony:             directory

    /var/log/cron:               empty

    /var/log/grubby_prune_debug: ASCII text

    /var/log/lastlog:            8086 relocatable (Microsoft)

    /var/log/maillog:            empty

    /var/log/messages:           empty

    /var/log/qemu-ga:            directory

    /var/log/rhsm:               directory

    /var/log/secure:             empty

    /var/log/spooler:            empty

    /var/log/tallylog:           empty

    /var/log/tuned:              directory

    /var/log/wtmp:               empty

    /var/log/yum.log:            ASCII text

    [root@Daniel-R480 ~]# file `ls /var/log`

    anaconda:           cannot open (No such file or directory)

    audit:              cannot open (No such file or directory)

    boot.log:           cannot open (No such file or directory)

    btmp:               cannot open (No such file or directory)

    chrony:             cannot open (No such file or directory)

    cron:               cannot open (No such file or directory)

    grubby_prune_debug: cannot open (No such file or directory)

    lastlog:            cannot open (No such file or directory)

    maillog:            cannot open (No such file or directory)

    messages:           cannot open (No such file or directory)

    qemu-ga:            cannot open (No such file or directory)

    rhsm:               cannot open (No such file or directory)

    secure:             cannot open (No such file or directory)

    spooler:            cannot open (No such file or directory)

    tallylog:           cannot open (No such file or directory)

    tuned:              cannot open (No such file or directory)

    wtmp:               cannot open (No such file or directory)

    yum.log:            cannot open (No such file or directory)

    [root@Daniel-R480 ~]# cd /var/log

    [root@Daniel-R480 log]# file `ls /var/log`

    anaconda:           directory

    audit:              directory

    boot.log:           empty

    btmp:               empty

    chrony:             directory

    cron:               empty

    grubby_prune_debug: ASCII text

    lastlog:            8086 relocatable (Microsoft)

    maillog:            empty

    messages:           empty

    qemu-ga:            directory

    rhsm:               directory

    secure:             empty

    spooler:            empty

    tallylog:           empty

    tuned:              directory

    wtmp:               empty

    yum.log:            ASCII text

    [root@Daniel-R480 log]#

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

    [root@Daniel-R480 ~]# head -6 /etc/inittab | tail -1

    #

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

    [root@Daniel-R480 ~]#  tail -9 /etc/passwd | head -1 | cut -d: -f1,7 | tee /tmp/users

    user9:/bin/bash

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

    [root@Daniel-R480 ~]# ls -d /etc/pa* | wc -l

    3

    [root@Daniel-R480 ~]#

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

    [root@Daniel-R480 ~]# echo “alias cls=clear” >> ~/.bashrc

    [root@Daniel-R480 ~]# cat ~/.bashrc

    # .bashrc

    # User specific aliases and functions

    alias rm=’rm -i’

    alias cp=’cp -i’

    alias mv=’mv -i’

    # Source global definitions

    if [ -f /etc/bashrc ]; then

            . /etc/bashrc

    fi

    alias cls=clear

    [root@Daniel-R480 ~]#

10、用户权限管理(基本权限及特殊权限SUID)

10.1 基本权限

10.1.1 权限分类

    权限分为r, w, x

    1、对于文件来说:

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

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

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

    2、对于目录来说:

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

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

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

    3、rwx和数值对照关系

        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

    4、对应三类用户:

        u: 属主  g: 属组 o: 其它用户

10.2 特殊权限(passwd中显示s的权限)

    10.2.1 特殊权限分类

    1、SUID:

         运行某程序时,相应进程的属主是程序文件自身的属主,而不是启动者;

            chmod u+s FILE

            chmod u-s FILE

        如果FILE本身原来就有执行权限,则SUID显示为s;否则显示S;

    2、SGID:

        运行某程序时,相应进程的属组是程序文件自身的属组,而不是启动者所属的基本组;

            chmod g+s FILE

            chmod g-s FILE

        组develop team,用户 hadoop, hbase, hive

        在/tmp/project/文件夹中给其分配SGID权限,则develop team里的所有用户都可以更改删除任何文件

                develop

    3、Sticky:

     在一个公共目录,每个都可以创建文件,删除自己的文件,但不能删除别人的文件;

        chmod o+t DIR

        chmod o-t DIR

    4、组合及对应数字

        SUID SGID Sticky

        000: 

        001: 

        …

        110: 

        111:

        chmod 5755 /backup/test(5表示特殊权限)

        umask 0022

        umask 

10.3 chown:

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

    # chown USERNAME file,…将后面文件的属主改为指定用户

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

        –reference=/path/to/somefile file,…将文件的属主属组更改为和reference对应文件一样

    # chgrp GRPNAME file,…更改文件属组为指定的group

        -R

        –reference=/path/to/somefile file,…

        [root@Daniel-R480 tmp]# chown apache hi

        [root@Daniel-R480 tmp]# ll

        total 12

        -rw-r–r– 1 apache root    0 Jun  4 18:30 hi

        -rwx—— 1 root   root 4733 Jan 29  2019 ks-script-5qnQJp

        -rwx—— 1 root   root  836 Jan 29  2019 ks-script-QveTmi

        -rw——- 1 root   root    0 Jan 29  2019 yum.log

        [root@Daniel-R480 tmp]# chown –reference=./yum.log ./hi

        [root@Daniel-R480 tmp]# ll

        total 12

        -rw-r–r– 1 root root    0 Jun  4 18:30 hi

        -rwx—— 1 root root 4733 Jan 29  2019 ks-script-5qnQJp

        -rwx—— 1 root root  836 Jan 29  2019 ks-script-QveTmi

        -rw——- 1 root root    0 Jan 29  2019 yum.log

        [root@Daniel-R480 tmp]#

    chown USERNAME:GRPNAME file,…

    chown USERNAME.GRPNAME file,…

        [root@Daniel-R480 tmp]# ll

        total 12

        -rw-r–r– 1 root root    0 Jun  4 18:30 hi

        -rwx—— 1 root root 4733 Jan 29  2019 ks-script-5qnQJp

        -rwx—— 1 root root  836 Jan 29  2019 ks-script-QveTmi

        -rw——- 1 root root    0 Jan 29  2019 yum.log

        [root@Daniel-R480 tmp]#

        [root@Daniel-R480 tmp]#

        [root@Daniel-R480 tmp]# chown apache:apache ./hi

        [root@Daniel-R480 tmp]# ll

        total 12

        -rw-r–r– 1 apache apache    0 Jun  4 18:30 hi

        -rwx—— 1 root   root   4733 Jan 29  2019 ks-script-5qnQJp

        -rwx—— 1 root   root    836 Jan 29  2019 ks-script-QveTmi

        -rw——- 1 root   root      0 Jan 29  2019 yum.log

        [root@Daniel-R480 tmp]# chown :root /tmp/hi

        [root@Daniel-R480 tmp]# ll

        total 12

        -rw-r–r– 1 apache root    0 Jun  4 18:30 hi

        -rwx—— 1 root   root 4733 Jan 29  2019 ks-script-5qnQJp

        -rwx—— 1 root   root  836 Jan 29  2019 ks-script-QveTmi

        -rw——- 1 root   root    0 Jan 29  2019 yum.log

        [root@Daniel-R480 tmp]# chown –reference=/tmp/yum.log ./hi

        [root@Daniel-R480 tmp]# ll

        total 12

        -rw-r–r– 1 root root    0 Jun  4 18:30 hi

        -rwx—— 1 root root 4733 Jan 29  2019 ks-script-5qnQJp

        -rwx—— 1 root root  836 Jan 29  2019 ks-script-QveTmi

        -rw——- 1 root root    0 Jan 29  2019 yum.log

        [root@Daniel-R480 tmp]#

10.4 chmod: 

    修改文件的权限

    1、修改三类用户的权限:

        chmod MODE file,…

            -R修改目录及其内部文件的权限

            –reference=/path/to/somefile file,…

        [root@Daniel-R480 tmp]# ll

        total 12

        -rw-r–r– 1 root root    0 Jun  4 18:30 hi

        -rwx—— 1 root root 4733 Jan 29  2019 ks-script-5qnQJp

        -rwx—— 1 root root  836 Jan 29  2019 ks-script-QveTmi

        -rw——- 1 root root    0 Jan 29  2019 yum.log

        [root@Daniel-R480 tmp]# chmod 777 ./hi

        [root@Daniel-R480 tmp]# ll

        total 12

        -rwxrwxrwx 1 root root    0 Jun  4 18:30 hi

        -rwx—— 1 root root 4733 Jan 29  2019 ks-script-5qnQJp

        -rwx—— 1 root root  836 Jan 29  2019 ks-script-QveTmi

        -rw——- 1 root root    0 Jan 29  2019 yum.log

        [root@Daniel-R480 tmp]#

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

        u,g,o,a

        u: 属主  g: 属组 o: 其它用户

        chmod 用户类别=MODE file,…

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

        u,g,o,a

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

        [root@Daniel-R480 ~]# chmod g-r inittab

        [root@Daniel-R480 ~]# chmod 777 inittab

        [root@Daniel-R480 ~]#

练习:

    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

    chmod -R 700 /home/openstack

    [root@Daniel-R480 ~]# useradd -M openstack

    [root@Daniel-R480 ~]# cp -r /etc/skel /home/openstack

    [root@Daniel-R480 ~]# chown -R openstack:openstack /home/openstack

    [root@Daniel-R480 ~]# chmod -R go= /home/openstack

    [root@Daniel-R480 ~]# ll /home/openstack/

    total 0

    su – openstack(测试创建是否正常)

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

    无密码无法登陆,但是可以用管理员账户su过去

    opensll:创建密码的密文的命令

    [root@Daniel-R480 ~]# groupadd -g 5000 hive

    [root@Daniel-R480 ~]# groupadd mygroup

    [root@Daniel-R480 ~]# useradd -g hive -G mygroup -M hive

    [root@Daniel-R480 ~]# su – hive

    su: warning: cannot change directory to /home/hive: No such file or directory

    -bash-4.2$

10.5 umask

    umask:遮罩码

        666-umask:创建文件的默认权限

        777-umask:创建文件夹的默认权限

    [hive@Daniel-R480 ~]$ umask

    0002

    [hive@Daniel-R480 ~]$ umask 0022

    [hive@Daniel-R480 ~]$ touch hellosa

    [hive@Daniel-R480 ~]$ ll

    total 0

    -rw-rw-r– 1 hive hive 0 Jun  7 09:50 hellosa

    [hive@Daniel-R480 ~]$

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

    例:umask: 023

        文件权限:666-023=643 X 

        目录权限:777-023=754

    [hive@Daniel-R480 ~]$

    [hive@Daniel-R480 ~]$ umask 023

    [hive@Daniel-R480 ~]$ touch hellosa

    [hiv1e@Daniel-R480 ~]$ mkdir test

    [hive@Daniel-R480 ~]$ ll

    total 0

    -rw-r–r– 1 hive hive    0 Jun  7 09:52 hellosa

    drwxr-xr– 1 hive hive 4096 Jun  7 09:52 test

    [hive@Daniel-R480 ~]$

    用户重新登陆以后umask会重新配置,恢复默认

10.6 SHELL

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

    1、登录式shell:(完全切换)

        正常通过某终端登录

        su – USERNAME 

        su -l USERNAME

    2、非登录式shell:(半切换)

        su USERNAME

        图形终端下打开命令窗口

        自动执行的shell脚本

10.7 bash的配置文件:

    1、全局配置文件

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

    2、个人配置文件

        ~/.bash_profile, ~/.bashrc

        用户登录时优先使用个人配置文件

    3、profile类的文件:

        设定环境变量

        运行命令或脚本

    4、bashrc类的文件:

        设定本地变量

        定义命令别名

    5、shell如何读取配置文件?

        登录式

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

        非登录式

        ~/.bashrc –> /etc/bashrc –> /etc/profile.d/*.sh

    设置用户登录时显示hello

</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>&nbsp;&nbsp;[root@Daniel-R480&nbsp;~]#&nbsp;vim&nbsp;./.bash_profile</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>&nbsp;&nbsp;&nbsp;&nbsp;[root@Daniel-R480&nbsp;~]#&nbsp;su&nbsp;-&nbsp;root</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>&nbsp;&nbsp;&nbsp;&nbsp;Last&nbsp;login:&nbsp;Mon&nbsp;Jun&nbsp;&nbsp;7&nbsp;10:03:01&nbsp;CST&nbsp;2021&nbsp;on&nbsp;tty1</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>&nbsp;&nbsp;&nbsp;&nbsp;hello</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>&nbsp;&nbsp;&nbsp;&nbsp;[root@Daniel-R480&nbsp;~]#</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>#&nbsp;.bash_profile</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>#&nbsp;Get&nbsp;the&nbsp;aliases&nbsp;and&nbsp;functions</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>if&nbsp;[&nbsp;-f&nbsp;~/.bashrc&nbsp;];&nbsp;then</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.&nbsp;~/.bashrc</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>fi</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>#&nbsp;User&nbsp;specific&nbsp;environment&nbsp;and&nbsp;startup&nbsp;programs</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>PATH=$PATH:$HOME/bin</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>export&nbsp;PATH</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>echo hello</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>

bash: 脚本解释器

9、管理用户和组

9.1 用户组管理常用命令和文件

9.1.1 常用命令

    用户管理:

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

    组管理:

        groupadd, groupdel, groupmod, gpasswd

    权限管理:

        chown, chgrp, chmod, umask

9.1.3 常用文件及其内容

    /etc/passwd:

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

    [root@Daniel-R480 default]# cat /etc/passwd

    root:x:0:0:root:/root:/bin/bash

    bin:x:1:1:bin:/bin:/sbin/nologin

    daemon:x:2:2:daemon:/sbin:/sbin/nologin

    /etc/group:

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

    [root@Daniel-R480 default]# cat /etc/group

    root:x:0:

    bin:x:1:

    daemon:x:2:

    sys:x:3:

    adm:x:4:

    tty:x:5:

    disk:x:6:

    /etc/shadow:

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

    [root@Daniel-R480 default]# cat /etc/shadow

    root:$6$PFQ4zANu$LyrKxl8kGT/lYge0N0zj1f1ltbuvXaJIFale65FJ4gA/llvFXABl6kOL9KvQTMJ01W6Jxu81GSLx9qIBnq4Sv1:18782:0:99999:7:::

    bin:*:17834:0:99999:7:::

    daemon:*:17834:0:99999:7:::

    adm:*:17834:0:99999:7:::

9.2 添加用户

    useradd  [options]  USERNAME 

            -u UID 指定UID

            -g GID(基本组)

            -G GID,…  (附加组)

            -c “COMMENT” 指定注释信息

            -d /path/to/directory 指定某个目录

            -s SHELL  指定shell路径(一定要在/etc/shells里面)

            -m -k 创建用户家目录并且将/etc/skel/下面的用户配置文件导过来

            -M 不为用户创建家目录

            -r: 添加系统用户

    /etc/login.defs:文件用于在Linux创建用户时,对用户的一些基本属性做默认设置,例如指定用户 UID 和 GID 的范围,用户的过期时间,密码的最大长度,等等。

    [root@Daniel-R480 ~]# ueradd -u 1000 test

    -bash: ueradd: command not found

    [root@Daniel-R480 ~]# useradd -u 1000 test

    useradd: UID 1000 is not unique

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# useradd -u 10011 test

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# tail -1 /etc/passwd

    test:x:10011:10011::/home/test:/bin/bash

    [root@Daniel-R480 ~]# useradd -g hellosa test1

    useradd: group ‘hellosa’ does not exist

    [root@Daniel-R480 ~]# useradd -g mygroup test1

    useradd: group ‘mygroup’ does not exist

    [root@Daniel-R480 ~]# groupadd test

    groupadd: group ‘test’ already exists

    [root@Daniel-R480 ~]# useradd -g test test1

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# tail -1 /etc/passwd

    test1:x:10012:10011::/home/test1:/bin/bash

    [root@Daniel-R480 ~]# useradd -G test test2

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# tail -1 /etc/passwd

    test2:x:10013:10013::/home/test2:/bin/bash

    [root@Daniel-R480 ~]# useradd -s /sbin/nologin test3

    [root@Daniel-R480 ~]# su – test3

    This account is currently not available.

    [root@Daniel-R480 ~]# useradd -M test4

    [root@Daniel-R480 ~]# su – test4

    su: warning: cannot change directory to /home/test4: No such file or directory

    -bash-4.2$

    -bash-4.2$

    -bash-4.2$

    -bash-4.2$

    -bash-4.2$ pwd

    /root

    -bash-4.2$ exit

    logout

    环境变量:

        PATH

        HISTSIZE

        SHELL(保存当前用户的默认shell)

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

9.3 用户删除

    userdel:删除用户

    userdel [option] USERNAME(默认不删除用户的家目录)

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

    id:查看用户的帐号属性信息,可直接加用户

        -u 查看UID

        -g 查看可用的GID

        -G 查看所有的GID

        -n 查看名称

    [root@Daniel-R480 ~]# id test

    uid=10011(test) gid=10011(test) groups=10011(test)

    [root@Daniel-R480 ~]# id -u test

    10011

    [root@Daniel-R480 ~]# id -g test

    10011

    [root@Daniel-R480 ~]# id -G test

    10011

    [root@Daniel-R480 ~]# id -u -n  test

    test

    [root@Daniel-R480 ~]# id -g -n  test

    test

    [root@Daniel-R480 ~]# id -G -n  test

    test

    finger: 查看用户帐号信息

    finger USERNAME

    [root@Daniel-R480 ~]# finger test

    Login: test                             Name:

    Directory: /home/test                   Shell: /bin/bash

    Never logged in.

    No mail.

    No Plan.

9.4 修改用户帐号属性:

    usermod

        -u UID 修改用户UID

        -g GID 修改用户GID

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

        -c 使用注释信息

        -d -m:给用户创建新的家目录,并将之前家目录的文件拷贝到新的家目录中

        -s 修改用户shell

        -l loginname 修改用户登录名

        -L:锁定帐号

        -U:解锁帐号

    [root@Daniel-R480 ~]# id test

    uid=10011(test) gid=10011(test) groups=10011(test)

    [root@Daniel-R480 ~]# usermod -u 2002 test

    [root@Daniel-R480 ~]# id test

    uid=2002(test) gid=10011(test) groups=10011(test)

    chsh:

     修改用户的默认shell

    [root@Daniel-R480 ~]# finger test

    Login: test                             Name:

    Directory: /home/test                   Shell: /bin/bash

    Never logged in.

    No mail.

    No Plan.

    [root@Daniel-R480 ~]# id test

    uid=10011(test) gid=10011(test) groups=10011(test)

    [root@Daniel-R480 ~]# usermod -u 2002 test

    [root@Daniel-R480 ~]# id test

    uid=2002(test) gid=10011(test) groups=10011(test)

    [root@Daniel-R480 ~]# finger test

    Login: test                             Name:

    Directory: /home/test                   Shell: /bin/bash

    Never logged in.

    No mail.

    No Plan.

    [root@Daniel-R480 ~]# chsh test

    Changing shell for test.

    New shell [/bin/bash]: /bin/tcsh

    chsh: “/bin/tcsh” does not exist

    [root@Daniel-R480 ~]# cat /etc/shells

    /bin/sh

    /bin/bash

    /usr/bin/sh

    /usr/bin/bash

    [root@Daniel-R480 ~]# cat /etc/shells chsh test

    /bin/sh

    /bin/bash

    /usr/bin/sh

    /usr/bin/bash

    cat: chsh: No such file or directory

    cat: test: No such file or directory

    [root@Daniel-R480 ~]# chsh test

    Changing shell for test.

    New shell [/bin/bash]: /bin/sh

    Shell changed.

    [root@Daniel-R480 ~]# finger test

    Login: test                             Name:

    Directory: /home/test                   Shell: /bin/sh

    Never logged in.

    No mail.

    No Plan.

    [root@Daniel-R480 ~]#

    chfn:

           修改注释信息

    chage:

          改变密码过期信息

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

        -E: 过期时间

        -I:非活动时间

        -m: 最短使用期限

        -M: 最长使用期限

        -W: 警告时间

9.5 密码管理:

    passwd [USERNAME]

        –stdin 用标准输入读取密码,可用来在脚本中创建用户账号及密码

        -l 锁定用户密码

        -u 解锁用户密码

        -d: 删除用户密码

        -n:设定密码最短使用期限

        -x:设定密码最长使用期限

    [root@Daniel-R480 ~]# echo “redhat”

    redhat

    [root@Daniel-R480 ~]# echo “redhat” | passwd –stdin test

    Changing password for user test.

    passwd: all authentication tokens updated successfully.

    [root@Daniel-R480 ~]# tail /etc/shadow

    nfsnobody:!!:17924::::::

    sshd:!!:17924::::::

    postfix:!!:17924::::::

    chrony:!!:17924::::::

    daniel:$6$e6rwtpqp$awkNfQl9GtXO7vJNrRrlyJfIE7OcxzOuJZBAR3OueOSBIPtK9ZyuJoBH1s9Ln666KZD8zr9pSnsRg90Wiupj7.:18782:0:99999:7:::

    test:$6$c5y8U2BO$7AFRriEzYrC2qiH7DeQrl9sMpswUCpFzJ4n/2wcwUifUhlwSKsZzWlv0l75WDEvSTKAeGi3kxzmkumgk0p1ZX0:18782:0:99999:7:::

    test1:!!:18782:0:99999:7:::

    test2:!!:18782:0:99999:7:::

    test3:!!:18782:0:99999:7:::

    test4:!!:18782:0:99999:7:::

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# passwd -d test

    Removing password for user test.

    passwd: Success

    [root@Daniel-R480 ~]# tail /etc/shadow

    nfsnobody:!!:17924::::::

    sshd:!!:17924::::::

    postfix:!!:17924::::::

    chrony:!!:17924::::::

    daniel:$6$e6rwtpqp$awkNfQl9GtXO7vJNrRrlyJfIE7OcxzOuJZBAR3OueOSBIPtK9ZyuJoBH1s9Ln666KZD8zr9pSnsRg90Wiupj7.:18782:0:99999:7:::

    test::18782:0:99999:7:::

    test1:!!:18782:0:99999:7:::

    test2:!!:18782:0:99999:7:::

    test3:!!:18782:0:99999:7:::

    test4:!!:18782:0:99999:7:::

    [root@Daniel-R480 ~]#

    pwck:(passwd check)检查用户帐号完整性

    [root@Daniel-R480 ~]# pwck

    user ‘ftp’: directory ‘/var/ftp’ does not exist

    user ‘test4’: directory ‘/home/test4’ does not exist

    pwck: no changes

    [root@Daniel-R480 ~]#

9.6 组管理:

    1、groupadd 创建组:

        -g GID指定gid

        -r:添加为系统组

    [root@Daniel-R480 ~]# useradd -r apache

    [root@Daniel-R480 ~]# tail -1 /etc/passwd

    apache:x:997:994::/home/apache:/bin/bash

    [root@Daniel-R480 ~]# groupadd -r nginx

    [root@Daniel-R480 ~]# tail -1 /etc/group

    nginx:x:993:

    [root@Daniel-R480 ~]#

    2、groupmod 修改组信息

        -g GID 修改GID

        -n GRPNAME 修改组名

    3、groupdel 删除组

    4、gpasswd:为组设定密码

    newgrp 为用户临时指定新的组

    [root@Daniel-R480 ~]# gpasswd test

    Changing the password for group test

    New Password:

    Re-enter new password:

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]#

    [root@Daniel-R480 ~]# newgrp test

    [root@Daniel-R480 ~]# su – apache

    su: warning: cannot change directory to /home/apache: No such file or directory

    -bash-4.2$

    -bash-4.2$

    -bash-4.2$ newgrp test

    Password:

    bash-4.2$ ginger

练习:

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

    [root@Daniel-R480 ~]# groupadd -g 3003 distro

    [root@Daniel-R480 ~]# groupadd linux

    [root@Daniel-R480 ~]# useradd -u 2002 -g distro -G linux mandriva

    [root@Daniel-R480 ~]# id mandriva

    uid=2002(mandriva) gid=3003(distro) groups=3003(distro),3004(linux)

    [root@Daniel-R480 ~]#

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

    [root@Daniel-R480 ~]# useradd -c “Fedora Community” -s /bin/tcsh fedora

    [root@Daniel-R480 ~]# tail -1 /etc/passwd

    fedora:x:2003:2003:Fedora Community:/home/fedora:/bin/tcsh

    [root@Daniel-R480 ~]#

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

    [root@Daniel-R480 ~]# usermod -u 4004 -g linux -G distro,fedora mandriva

    [root@Daniel-R480 ~]# id mandriva

    uid=4004(mandriva) gid=3004(linux) groups=3004(linux),3003(distro),2003(fedora)

    [root@Daniel-R480 ~]#

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

    [root@Daniel-R480 ~]# passwd -n 2 -x 50 fedora

    Adjusting aging data for user fedora.

    passwd: Success

    [root@Daniel-R480 ~]# tail -1 /etc/passwd

    fedora:x:2003:2003:Fedora Community:/home/fedora:/bin/tcsh

    [root@Daniel-R480 ~]# tail -1 /etc/shadow

    fedora:!!:18810:2:50:7:::

    [root@Daniel-R480 ~]#

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

    [root@Daniel-R480 ~]# usermod -s /bin/sh mandriva

    [root@Daniel-R480 ~]# usermod -s /bin/bash mandriva

    [root@Daniel-R480 ~]# tail -2 /etc/passwd

    mandriva:x:4004:3004::/home/mandriva:/bin/bash

    fedora:x:2003:2003:Fedora Community:/home/fedora:/bin/tcsh

    [root@Daniel-R480 ~]#

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

    [root@Daniel-R480 ~]# useradd -r -s /sbin/nologin hbase

    [root@Daniel-R480 ~]# su hbase

    This account is currently not available.

    [root@Daniel-R480 ~]#

8、Linux用户及权限

8.1 进程,库,用户,组,权限

    8.1.1 进程

    进程的安全上下文(secure context):

    进程代理进程的发起者调用所需的库在内存中进行运行,能访问哪些文件取决于发起进程的用户

    8.1.2 库

    库称之为共享库

    8.1.3 用户,组和权限

    linux的一切文件和硬件都称之为是计算资源

    用户:获取资源和服务的凭证,标识符

    组:关联用户和权限的容器,为了方便的指派权限,标识符

    权限:定义了资源和服务的访问能力)

    文件:被访问的对象

    文件的属主,属组和其他用户的访问权限

8.2 权限

8.2.1 权限分类

    权限分为r, w, x

    对于文件来说:

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

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

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

    对于目录来说:

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

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

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

8.2.2 rwx和数值对应关系

    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(常用权限,读和执行)

8.3 用户和组

8.3.1 UID,GID和shadow

    用户:UID(标识用户的代码), /etc/passwd

    组:GID(标识组的代码), /etc/group

    解析:将用户之类的信息转换为系统能识别出来的ID号

    影子口令(将用户的密码放在另一个安全的位置):

    用户密码放置位置:/etc/shadow

    组密码放置位置:/etc/gshadow

8.3.2 用户和组分类

    用户类别(大体上分为两个):

           管理员:ID号永远为0

           普通用户:ID号为caca 1-65535

               系统用户:1-499(专门用来运行系统服务的用户,不需要登录系统)

               一般用户:500-60000

    用户组类别1:

           管理员组:

           普通组:

              系统组:

              一般组:

    用户组类别2:

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

        基本组:用户的默认组(此组里面只有本用户一个用户)

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

    进程:文件查看运行进程的用户,如果用户无权限访问,则查看此用户的组,如果组也无权限访问,则此进程无法正常运行

    对象:被访问的对象

8.3.3 passwd文件

    [root@Daniel-R480 ~]# cat /etc/passwd

    root:x:0:0:root:/root:/bin/bash

    bin:x:1:1:bin:/bin:/sbin/nologin

    daemon:x:2:2:daemon:/sbin:/sbin/nologin

    adm:x:3:4:adm:/var/adm:/sbin/nologin

    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

    sync:x:5:0:sync:/sbin:/bin/sync

    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

    halt:x:7:0:halt:/sbin:/sbin/halt

    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

    operator:x:11:0:operator:/root:/sbin/nologin

    games:x:12:100:games:/usr/games:/sbin/nologin

    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

    nobody:x:99:99:Nobody:/:/sbin/nologin

    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin

    dbus:x:81:81:System message bus:/:/sbin/nologin

    polkitd:x:999:998:User for polkitd:/:/sbin/nologin

    rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin

    rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin

    nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

    postfix:x:89:89::/var/spool/postfix:/sbin/nologin

    chrony:x:998:995::/var/lib/chrony:/sbin/nologin

    passwd文件显示顺序

        account: 登录名

        password: 密码

        UID:用户的ID号

        GID:基本组ID

        comment: 注释,用户的全名等信息

        HOME DIR:家目录

        SHELL:用户的默认shell,配置为不合法的shell无法登陆或者有些用户直接设置不允许登陆

8.3.4 用户的shell

    查看合法shell

    [root@Daniel-R480 ~]# cat /etc/shells

    /bin/sh

    /bin/bash

    /usr/bin/sh

    /usr/bin/bash

8.3.5 shadow

    密码放置位置/etc/shadow

    [root@Daniel-R480 ~]# cat /etc/shadow

    root:!!:17924:0:99999:7:::

    bin:*:17834:0:99999:7:::

    daemon:*:17834:0:99999:7:::

    shadow每一位代表的内容

        account: 登录名

        encrypted password: 加密的密码

        1970年1月1日到密码上次更改的天数

        密码能使用的天数,0表示不限制

        密码快要过期的天数

        宽限的只能改密码的几天

8.4 数据加密

    数据加密方法:

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

        (2)公钥加密(非对称加密):每个密码都成对儿出现,一个为私钥(secret key),一个为公钥(public key),一个用来加密,一个用来解密

        (3)单向加密,散列加密(可以由明文取得密文,但不能由密文取得明文):提取数据特征码,常用于数据完整性校验

    单向加密特点

        雪崩效应(蝴蝶效应):初始条件的微小改变会引起结果的巨大改变

        [root@Daniel-R480 ~]# cp /etc/inittab ./

        [root@Daniel-R480 ~]# md5sum inittab

        66a88d6c4d693170753ea3382f8bc150  inittab

        [root@Daniel-R480 ~]# vim inittab

        -bash: vim: command not found

        [root@Daniel-R480 ~]# vi inittab

        [root@Daniel-R480 ~]# md5sum inittab

        568c018aebe36cf208fc32c465e4b120  inittab

        定长输出

            MD5:Message Digest, 128位定长输出

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

        密码前面一般会有加上的杂质(salt),防止相同用户的密码显示的密文相同

7、bash及其特性

7.1 shell,用户,进程和程序

shell: 程序和内核交流的外壳

    GUI:Gnome, KDE, Xfce

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

只有一个程序,但可以打开多个进程

进程是程序的副本,进程是程序执行的实例,在内存当中运行

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

7.2 bash:

7.2.1 用户分类

    分为管理员用户和普通用户,用不同的字符标识

        root:         #

        普通用户:   $

7.2.2 shell和子shell

    shell当中包含着 shell,子shell,可以同时打开多个shell,还可以交互打开

    父shell和子shell,并不知道彼此的存在

    bash–bash

    [root@Daniel-R480 ~]# su daniel

    [daniel@Daniel-R480 root]$

7.2.3 bash:特点及功能

    1、命令历史、命令补全

    2、管道、重定向

    3、命令别名

    4、命令行编辑

    5、命令行展开

    6、文件名通配

    7、变量

    8、编程

7.2.4 命令行编辑:

1、光标跳转:

    Ctrl+a:跳到命令行首

    Ctrl+e:跳到命令行尾

    (图形界面可使用Ctrl+左右键跳到行首和行尾)

    Ctrl+d:删除对应的后面的字符

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

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

    Ctrl+l: 清屏

2、命令历史:

    查看命令历史:history

        -c:清空命令历史

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

        [daniel@localhost ~]$ history -d 459

        [daniel@localhost ~]$ history -d 460 10

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

        用户退出后命令会从缓存转移到家目录下的.bash_history当中

    PATH:命令搜索路径

    HISTSIZE: 命令历史缓冲区大小

    [daniel@localhost ~]$ echo $HISTSIZE

    1000

    命令历史的使用技巧:

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

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

        !!: 执行上一条命令;

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

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

        !$

        Esc+ .

        Alt+.   (本地支持,远程不支持)

    [root@Daniel-R480 ~]# cat calc.sh 

    #!/bin/bash

    #

    declare -i SUM=0

    for I in {1..100};do

        let SUM=$[$SUM+$I]

    done

    echo “The sum is : $SUM”

    [root@Daniel-R480 ~]# du !$

    du calc.sh

    0   calc.sh

    [root@Daniel-R480 ~]#

3、命令和路径补全:

    Linux 最小化安装时,是没有 tab 命令补全的,需要自己手动安装。

    # 安装

$ yum -y install bash-completion

    # 重新登录生效 

    PATH:环境变量路径正常,即可进行补全

    输入相应的开头,随后点击tab

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

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

4、命令别名和命令替换

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

        alias newname=oldname

        alias CMDALIAS=’COMMAND [options] [arguments]’

    [root@Daniel-R480 ~]# alias cl=clear

    [root@Daniel-R480 ~]# cl

    撤销别名,unalias +命令别名

        ualias CMDALIAS

    [root@Daniel-R480 ~]# unalias cl

    [root@Daniel-R480 ~]# cl

    -bash: cl: command not found

    [root@Daniel-R480 ~]# 

    \CMD(转义字符)

    \+命令可以取消命令别名

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

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

    file-2013-02-28-14-53-31.txt

    [daniel@localhost ~]$ touch file-$(date +%F-%H-%M-%S)

    [daniel@localhost ~]$ touch file-$(date +%F-%H-%M-%S)

    [daniel@localhost ~]$ ls

    a  file-2021-06-03-03-00-26  file-2021-06-03-03-00-31  heloy  m  test  test2  x

    [daniel@localhost /]$ echo “the current directory is $(pwd).”

    the current directory is /.

    [daniel@localhost /]$ cd /opt

    [daniel@localhost opt]$ !-2

    echo “the current directory is $(pwd).”

    the current directory is /opt.

    [daniel@localhost opt]$ 

    bash支持的引号:

        “: 命令替换

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

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

5、文件名通配, globbing

    *: 可匹配任意长度的任意字符

    [daniel@localhost ~]$ touch a asd adcs dfvsf fde dedas wdwa qwd

    [daniel@localhost ~]$ ls a*

    a  adcs  asd

    [daniel@localhost ~]$ ls a*d

    asd

    ?:可匹配任意单个字符

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

        [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可以查看这些列表

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

    [root@localhost daniel]# ls [[:alpha:]]*[[:alpha:]]

    a b  adcs  asd  dedas  dfvsf  fde  heloy  qwd  test  wdwa

练习:

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

    [root@Daniel-R480 test1]# touch {a123,cd6,c78m,”c1 my”,”m.z”,”k 67″,8yu,789}

    [root@Daniel-R480 test1]# ls

    789  8yu  a123  c1 my  c78m  cd6  k 67  m.z

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

    [root@Daniel-R480 test1]# ls [am]*

    a123  m.z

    [root@Daniel-R480 test1]# 

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

    [root@Daniel-R480 test1]# ls *[0-9]* 

    789  8yu  a123  c1 my  c78m  cd6  k 67

    [root@Daniel-R480 test1]# ls *[[:digit:]]*

    789  8yu  a123  c1 my  c78m  cd6  k 67

    [root@Daniel-R480 test1]# 

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

    [root@Daniel-R480 test1]# ls *[^[:space:]]*[0-9] 

    789  a123  cd6  k 67

    [root@Daniel-R480 test1]# 

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

    [root@Daniel-R480 test1]# ls *[^[:alnum:]]*

    c1 my  k 67  m.z

6、常用文本处理命令

6.1 知识回顾

    做一件事

    2-3年:专家

    5年以上:权威

    操作系统功能

    运行程序,设备管理,软件管理,进程管理,网络管理

    目录管理:

        ls、cd、pwd、mkdir、rmdir、tree

    文件管理:

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

    日期时间:

        date、clock、hwclock、cal

6.2 文本处理

6.2.1 查看文本:

cat、tac、more、less、head、tail

1、cat

连接并显示从首部到尾部(tac显示从尾部到首部)

    -n:显示行数

    -E:显示行结束符(linux行结束符号为$,windows行结束符号为enter+$)

    [root@Daniel-R480 ~]# cat calc.sh 

    #!/bin/bash

    #

    declare -i SUM=0

    for I in {1..100};do

        let SUM=$[$SUM+$I]

    done

    echo “The sum is : $SUM”

    [root@Daniel-R480 ~]# tac calc.sh 

    echo “The sum is : $SUM”

    done

        let SUM=$[$SUM+$I]

    for I in {1..100};do

    declare -i SUM=0

    #

    #!/bin/bash

    [root@Daniel-R480 ~]# cat -n calc.sh 

         1  #!/bin/bash

         2  #

         3  declare -i SUM=0

         4  for I in {1..100};do

         5      let SUM=$[$SUM+$I]

         6  done

         7  

         8  echo “The sum is : $SUM”

    [root@Daniel-R480 ~]# cat -E calc.sh 

    #!/bin/bash$

    #$

    declare -i SUM=0$

    for I in {1..100};do$

        let SUM=$[$SUM+$I]$

    done$

    $

    echo “The sum is : $SUM”$

Ctrl+c终止当前任务,或者终止当前输入命令的动作

shift + pageup/pagedown 来上下翻页

2、分屏显示:more、less file

    more: 向后翻(空格翻一页,enter翻一行)

    less(man里面用less来打开文本): k键向前翻

3、查看文本的前几行或者后几行(head tail)

    (1)head:查看前n行 

        [daniel@localhost ~]$ head -n 2 /etc/inittab 

        # inittab is no longer used when using systemd.

    (2)tail:查看后n行

        [daniel@localhost ~]$ tail -2 /etc/inittab 

        # systemctl set-default TARGET.target

    head,tail不加任何选项默认为10行

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

6.2.2 文本处理:

cut、join、sed、awk

database:数据库(存放数据的库)

mysql:管理数据库的软件

关系型数据库:

表:二维表

文本文件:用:来分隔

Tom:23:male:2013/05/06

1、cut:

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

    -f: 指定要显示的字段

        -f 1,3

        -f 1-3

    [daniel@localhost ~]$ cut -d : -f1 /etc/passwd

    root

    bin

    daemon

    adm

    lp

2、sort(不影响源文件的次序,只影响现实的次序)

    sort:文本排序(默认不按数值大小排序)

        -n:数值排序

        -r: 降序

        -t: 字段分隔符

        -k: 以哪个字段为关键字进行排序

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

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

    [daniel@localhost ~]$ sort -t : -k3 -n /etc/passwd

    root:x:0:0:root:/root:/bin/bash

    bin:x:1:1:bin:/bin:/sbin/nologin

    daemon:x:2:2:daemon:/sbin:/sbin/nologin

    adm:x:3:4:adm:/var/adm:/sbin/nologin

    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

    sync:x:5:0:sync:/sbin:/bin/sync

    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

    halt:x:7:0:halt:/sbin:/sbin/halt

    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

    operator:x:11:0:operator:/root:/sbin/nologin

    games:x:12:100:games:/usr/games:/sbin/nologin

    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

    tcpdump:x:72:72::/:/sbin/nologin

    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin

    dbus:x:81:81:System message bus:/:/sbin/nologin

    postfix:x:89:89::/var/spool/postfix:/sbin/nologin

    nobody:x:99:99:Nobody:/:/sbin/nologin

    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin

    chrony:x:998:996::/var/lib/chrony:/sbin/nologin

    polkitd:x:999:997:User for polkitd:/:/sbin/nologin

    daniel:x:1000:1000:daniel:/home/daniel:/bin/bash

3、uniq: 报告重复的行,或者是略过重复的行

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

        -d: 只显示重复的行中的一个

        -D:显示重复的行的所有内容

        [daniel@localhost ~]$ uniq -d test

        78

        [daniel@localhost ~]$ uniq -D test

        78

        78

        [daniel@localhost ~]$ uniq -c test

              3 

              1 1212

              1 23

              1 4234

              1 324234

              1 3242

              1 123

              1 3444

              1 5656

              1 89

              2 78

4、wc文本统计

    wc (word count)输出为行数 单词数 字节数

        -l只显示行

        -w只显示单词数

        -c只显示字节

        -L最长的一行包含的字符数

    [daniel@localhost ~]$ wc /etc/fstab 

     12  60 541 /etc/fstab

    [daniel@localhost ~]$ wc -w /etc/fstab 

    60 /etc/fstab

    [daniel@localhost ~]$ wc -l /etc/fstab 

    12 /etc/fstab

    [daniel@localhost ~]$ wc -c /etc/fstab 

    541 /etc/fstab

    [daniel@localhost ~]$ wc -L /etc/fstab 

    93 /etc/fstab

5、tr-字符处理命令

    tr —— 转换或删除字符

    tr [OPTION]… SET1 [SET2]

    [daniel@localhost ~]$ tr ‘ab’ ‘AB’

    abcd^H

    ABcd

    able

    ABle

    acount

    Acount

    [daniel@localhost ~]$ tr ‘ab’ ‘AB’ < /etc/passwd

    root:x:0:0:root:/root:/Bin/BAsh

    Bin:x:1:1:Bin:/Bin:/sBin/nologin

    dAemon:x:2:2:dAemon:/sBin:/sBin/nologin

    Adm:x:3:4:Adm:/vAr/Adm:/sBin/nologin

    lp:x:4:7:lp:/vAr/spool/lpd:/sBin/nologin

    sync:x:5:0:sync:/sBin:/Bin/sync

    shutdown:x:6:0:shutdown:/sBin:/sBin/shutdown

    hAlt:x:7:0:hAlt:/sBin:/sBin/hAlt

    mAil:x:8:12:mAil:/vAr/spool/mAil:/sBin/nologin

    operAtor:x:11:0:operAtor:/root:/sBin/nologin

    gAmes:x:12:100:gAmes:/usr/gAmes:/sBin/nologin

    ftp:x:14:50:FTP User:/vAr/ftp:/sBin/nologin

    noBody:x:99:99:NoBody:/:/sBin/nologin

    systemd-network:x:192:192:systemd Network MAnAgement:/:/sBin/nologin

    dBus:x:81:81:System messAge Bus:/:/sBin/nologin

    polkitd:x:999:997:User for polkitd:/:/sBin/nologin

    postfix:x:89:89::/vAr/spool/postfix:/sBin/nologin

    sshd:x:74:74:Privilege-sepArAted SSH:/vAr/empty/sshd:/sBin/nologin

    chrony:x:998:996::/vAr/liB/chrony:/sBin/nologin

    dAniel:x:1000:1000:dAniel:/home/dAniel:/Bin/BAsh

    tcpdump:x:72:72::/:/sBin/nologin

    [daniel@localhost ~]$ tr ‘a-z’ ‘A-Z’ < /etc/passwd

    ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH

    BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN

    DAEMON:X:2:2:DAEMON:/SBIN:/SBIN/NOLOGIN

    ADM:X:3:4:ADM:/VAR/ADM:/SBIN/NOLOGIN

    LP:X:4:7:LP:/VAR/SPOOL/LPD:/SBIN/NOLOGIN

    SYNC:X:5:0:SYNC:/SBIN:/BIN/SYNC

    SHUTDOWN:X:6:0:SHUTDOWN:/SBIN:/SBIN/SHUTDOWN

    HALT:X:7:0:HALT:/SBIN:/SBIN/HALT

    MAIL:X:8:12:MAIL:/VAR/SPOOL/MAIL:/SBIN/NOLOGIN

    OPERATOR:X:11:0:OPERATOR:/ROOT:/SBIN/NOLOGIN

    GAMES:X:12:100:GAMES:/USR/GAMES:/SBIN/NOLOGIN

    FTP:X:14:50:FTP USER:/VAR/FTP:/SBIN/NOLOGIN

    NOBODY:X:99:99:NOBODY:/:/SBIN/NOLOGIN

    SYSTEMD-NETWORK:X:192:192:SYSTEMD NETWORK MANAGEMENT:/:/SBIN/NOLOGIN

    DBUS:X:81:81:SYSTEM MESSAGE BUS:/:/SBIN/NOLOGIN

    POLKITD:X:999:997:USER FOR POLKITD:/:/SBIN/NOLOGIN

    POSTFIX:X:89:89::/VAR/SPOOL/POSTFIX:/SBIN/NOLOGIN

    SSHD:X:74:74:PRIVILEGE-SEPARATED SSH:/VAR/EMPTY/SSHD:/SBIN/NOLOGIN

    CHRONY:X:998:996::/VAR/LIB/CHRONY:/SBIN/NOLOGIN

    DANIEL:X:1000:1000:DANIEL:/HOME/DANIEL:/BIN/BASH

    TCPDUMP:X:72:72::/:/SBIN/NOLOGIN

    tr -d: 删除出现在字符集中的所有字符

    [daniel@localhost ~]$ tr -d ‘ab’

    abcd

    cd

    adsde

    dsde

5、linux文件系统和常用文件管理命令

5.1 linux文件系统

5.1.1 file命令及其用法

          file + 文件或目录:查看文件类型

       可执行二进制文件格式: 

          Windows: PE

          Linux: ELF

5.1.2 Linux文件系统

          1、Linux文件系统的一些概念

                    rootfs: 根文件系统(每个文件系统都必须是根文件系统内的路径) 

                    FHS(文件系统层级标准):Linux

          2、Linux文件系统目录及各目录作用

           (1)/boot: 

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

             [daniel@localhost share]$ ls /boot

                     config-3.10.0-693.el7.x86_64

                     efi

                      grub(引导加载器)

                      grub2

                     initramfs-0-rescue-35642350c74f4b3287a0e5a8634f72ea.img

                      initramfs-3.10.0-693.el7.x86_64.img(系统启动的系统文件)

                     initramfs-3.10.0-693.el7.x86_64kdump.img

                     initrd-plymouth.img

                      symvers-3.10.0-693.el7.x86_64.gz

                     System.map-3.10.0-693.el7.x86_64

                     vmlinuz-0-rescue-35642350c74f4b3287a0e5a8634f72ea

                     vmlinuz-3.10.0-693.el7.x86_64(内核)

           (2)/dev: 设备文件

        设备文件:

            块设备:随机访问,可以随机访问任意位置的数据,数据块

            字符设备:线性访问,按字符为单位(鼠标和显示器)

            特殊设备没有大小,只有设备号

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

    (3)/etc:配置文件

        大多数程序的配置文件都放在此目录或者此目录的子目录

    (4)/home:用户的家目录

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

    (5)/root:管理员的家目录;

    (6)/lib:库文件

        静态库,  .a,便于程序单个运行使用

        动态库, .dll, .so (shared object),可以共享使用节省空间

        /lib/modules:内核模块文件

    (7)/media:挂载点目录

        挂载移动设备

    (8)/mnt:挂载点目录

        额外的临时文件系统

    (9)/opt:可选目录

        早期第三方程序的安装目录,现在通常放于/usr/local中

    (10)/proc:伪文件系统

        内核映射文件

    (11)/sys:伪文件系统

        跟硬件设备相关的属性映射文件

    (12)/tmp:临时文件

         /var/tmp,另外一个临时目录

    (13)/var:可变化的文件

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

        /sbin:管理命令

    (14)/usr:shared, read-only:全局共享的只读文件

        /usr/bin:系统启动之后运行正常系统功能的需要的文件

        /usr/sbin

        /usr/lib

        /usr/local:第三方软件的安装路径

            /usr/local/bin

            /usr/local/sbin

            /usr/local/lib

5.1.3 命名规则

    命名规则:

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

        2、不能使用/当文件名

        3、严格区分大小写

    绝对路径:相对于根节点的路径

    相对路径:相对于当前位置的路径

5.1.4 操作系统功能

    操作系统:

        运行程序

        设备管理

        软件管理

        进程管理

        网络管理

5.1.5 文件管理

    1、文件创建和删除

        (1)touch

            # touch 主要作用修改文件时间戳,也可用来创建文件(linux同一个目录下不能创建名称相同的文件夹和文件)

            -a 只改变访问时间

            -m 只改变修改时间

            -t 指定修改的时间

            -c 若文件不存在也不创建新文件

            stat file显示文件的状态信息

而文件夹确实是类似文本文件的方式存储的,文件夹可以看做文件inode:文件名组成的文本文件 (文件的属性信息存在inode的元信息中,可以用stat file查看)。只要文件夹内未发生文件的新增、删除、软链或文件夹内文件的inode (也称为索引节点)未改变,文件夹 (代表文件夹的文本文件)的时间戳就不会发生变化。

From <https://cloud.tencent.com/developer/article/1520817>

        [daniel@localhost ~]$ touch -m -t 201212121212 x

        [daniel@localhost ~]$ stat x

          File: ‘x’

          Size: 15          Blocks: 0          IO Block: 4096   directory

        Device: fd02h/64770d    Inode: 33554496    Links: 3

        Access: (0775/drwxrwxr-x)  Uid: ( 1000/  daniel)   Gid: ( 1000/  daniel)

        Context: unconfined_u:object_r:user_home_t:s0

        Access: 2021-06-01 12:55:16.734391633 -0400

        Modify: 2012-12-12 12:12:00.000000000 -0500

        Change: 2021-06-01 12:57:12.073157790 -0400

         Birth: –

                创建文件也可以使用文件编辑器来创建

                     word为字处理器,不是文本编辑器,处理的不仅仅是文本

        (2)ASCII码

             ASCII: 美国国家标准信息交换代码

            128不同的字符要存储在计算机上:

             计算机只能保存二进制:

            2^6=0,63  64个数字

            2^7=0,127 128个数字

            000 0000 – 111 1111

            ASCII:通过不同的位数变化来表示某个字符

            2^16: 65536

           字符标准:GB18030, GBK, GB2312(国标),Unicode(全球统一标准)

            0000 1001 0000 1110:上, 卫(它为ASCII码还是字符取决于使用的字符转换器)

                           linux文本剪辑器:nano

        (3)rm

        删除文件

            -i:删除前询问

            -f:强行删除,不接受提示

            -r:递归删除目录下所有文件

        rm -rf /

                    (ROOT用户可以通过此命令清理所有文件)

        任何操作之前确认一下,再操作

       (4)cp

        复制和移动文件cp

        cp: copy只有最后一个是目标,前面的都是源,默认只复制文件,不复制目录

        cp SRC DEST

            -r:递归复制目录和目录下的文件(不能覆盖文件)

            -p:保存用户原有的属主,属组和时间戳

            -P:保持文件自有的链接属性

            -a:归档复制,常用于备份

        cp file1 file2 file3

        可复制一个文件到一个文件

        也可复制多个文件到一个目录

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

说明: cp指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把前面指定的所有文件或目录复制到此目录中。若同时指定多个文件或目录,而最后的目的地并非一个已存在的目录,则会出现错误信息

参数:

     -a 或 –archive     此参数的效果和同时指定”-dpR”参数相同

     -b 或 –backup      删除、覆盖目的文件先备份,备份的文件或目录亦建立为符号链接,并指向源文件或目录链接的源文件或目录。假如没有加上这个参数,在复制过程中若遇到符号链接,则会直接复制源文件或目录

     -f 或 –force       强行复制文件或目录, 不论目的文件或目录是否已经存在

     -i 或 –interactive 覆盖文件之前先询问用户

     -l 或 –link        对源文件建立硬链接,而非复制文件

     -p 或 –preserve    保留源文件或目录的属性,包括所有者、所属组、权限与时间

     -P 或 –parents     保留源文件或目录的路径,此路径可以是绝对路径或相对路径,且目的目录必须已经丰在

     -r                  递归处理,将指定目录下的文件与子目录一并处理。若源文件或目录的形态,不属于目录或符号链接,则一律视为普通文件处理

     -R 或 –recursive   递归处理,将指定目录下的文件及子目录一并处理

     -s 或 –symbolic-link  对源文件建立符号链接,而非复制文件

     -S <备份字尾字符串> 或 –suffix=<备份字尾字符串> 用”-b”参数备份目的文件后,备份文件的字尾会被加上一个备份字符串。默认的备份字尾符串是符号”~”

     -u 或 –update      使用这项参数之后,只会在源文件的修改时间(Modification Time)较目的文件更新时,或是名称相互对应的目的文件并不存在,才复制文件

     -v 或 –verbose     显示执行过程

     -V <备份方式> 或 –version-control=<备份方式>  指定当备份文件时,备份文件名的命名方式,有以下3种:

                         1.numbered或t, 将使用备份编号,会在字尾加上~1~字符串,其数字编号依次递增

                         2.simple或never 将使用简单备份,默认的备份字尾字符串是~, 也可通过-S来指定

                         3.existing或nil将使用当前方式,程序会先检查是否存在着备份编号,若有则采用备份编号,若无则采用简单备份

     -x 或 –one-file-system  复制的文件或目录存放的文件系统,必须与cp指令执行时所处的文件系统相同,否则不复制,亦不处理位于其他分区的文件

     –help              显示在线帮助

     –sparse=<使用时机>  设置保存希疏文件的时机

     –version           显示版本

示例:

    .复制文件,只有源文件较目的文件的修改时间新时,才复制文件

     cp -u -v file1 file2

    .将文件file1复制成文件file2

     cp file1 file2

    .采用交互方式将文件file1复制成文件file2

     cp -i file1 file2

    .将文件file1复制成file2,因为目的文件已经存在,所以指定使用强制复制的模式

     cp -f file1 file2

    .将目录dir1复制成目录dir2

     cp -R file1 file2

    .同时将文件file1、file2、file3与目录dir1复制到dir2

cp -R file1 file2 file3 dir1 dir2

    .复制时保留文件属性

     cp -p a.txt tmp/

    .复制时保留文件的目录结构

     cp   –parents   /var/tmp/a.txt  ./temp/

    .复制时产生备份文件

     cp -b a.txt tmp/

    .复制时产生备份文件,尾标 ~1~格式

     cp -b -V t   a.txt /tmp    

    .指定备份文件尾标    

     cp -b -S _bak a.txt /tmp

        (5)mv: move

        移动文件

        mv SRC DEST

            mv -t DEST SRC将多个源文件复制到同一个目标

            mv -f DEST SRC 强制覆盖

        mv abc mn:将abc移动到当前目录,并且更改名称为mn

        (6)install

            install SRC DEST:可用来复制文件

                 -d 指定DIRECOTRY … :可用于创建目录

                 install -t DIRECTORY SRC…:把多个文件复制到同一个目录

5.1.6 目录管理

1、查看目录

                   ls

                   cd

                   pwd

2、mkdir

    mkdir:创建空目录,只有路径中的最后一个点才是要创建的目录

        -p:循环创建目录

        -v: verbose详细信息,显示创建过程

    例:mkdir /root/x/y/z

    创建多个目录

        /mnt/test/x/m,y

        (1)mkdir -pv /mnt/test/x/m /mnt/test/y

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

3、展开

    (1)波浪线展开

             ~USERNAME (波浪线展开):cd自动转换到用户家目录

       (2)命令行展开(花括号展开):

        /mnt/test/

        创建如下几个目录a_b, a_c, d_b, d_c

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

        所以可以写为{a,d}_{b,c}

        [root@Daniel-R480 ~]# mkdir -pv /mnt/test/{a,d}_{b,c}

        mkdir: created directory ‘/mnt/test/a_b’

        mkdir: created directory ‘/mnt/test/a_c’

        mkdir: created directory ‘/mnt/test/d_b’

        mkdir: created directory ‘/mnt/test/d_c’

        [root@Daniel-R480 ~]# ls /mnt/test/

        a_b  a_c  d_b  d_c

4、tree

    # tree:查看目录树

    [daniel@localhost ~]$ tree /mnt/test

    test

    ├── a_c

    ├── a_d

    ├── b_c

    └── b_d

5、rmdir

    删除目录:rmdir (remove directory)

        默认只能删除空目录

        -p:循环删除空文件夹

    [root@Daniel-R480 ~]# rmdir /mnt/test/

    rmdir: failed to remove ‘/mnt/test/’: Directory not empty

练习:

    1、创建目录

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

        [root@Daniel-R480 ~]# mkdir /mnt/{boot,sysroot}

        [root@Daniel-R480 ~]# ls /mnt

        boot  c  d  etst  sysroot  test

        [root@Daniel-R480 ~]# 

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

        [root@Daniel-R480 ~]# mkdir /mnt/boot/grub

        [root@Daniel-R480 ~]# ls /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

            [root@Daniel-R480 ~]# mkdir /mnt/sysroot/{proc,sys,bin,sbin,lib,usr,var,etc,dev,home,root,tmp}

            [root@Daniel-R480 ~]# mkdir /mnt/sysroot/usr/{bin,sbin,lib}

            [root@Daniel-R480 ~]# mkdir /mnt/sysroot/lib/modules

            [root@Daniel-R480 ~]# mkdir /mnt/sysroot/var/{run,log,lock}

            [root@Daniel-R480 ~]# touch /mnt/sysroot/etc/init.d

            [root@Daniel-R480 ~]# tree /mnt/sysroot/

            [root@Daniel-R480 ~]# tree /mnt/sysroot/

            /mnt/sysroot/

            ├── bin

            ├── dev

            ├── etc

            │   └── init.d

            ├── home

            ├── lib

            │   └── modules

            ├── proc

            ├── root

            ├── sbin

            ├── sys

            ├── tmp

            ├── usr

            │   ├── bin

            │   ├── lib

            │   └── sbin

            └── var

                ├── lock

                ├── log

                └── run

 作业1:

    1、创建目录/backup

        # mkdir -v /backup

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

        cp

            -r 

            -p

            -d

        # 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命令是否可以显示某目录的整体大小,即包括其内部的所有文件的整体大小?

    [root@Daniel-R480 tmp]# ls -lht

    total 516K

    -rw-r–r– 1 root root   18 Jun 18 18:01 b

    -rw-r–r– 1 root root   12 Jun 18 17:36 a

    -rwxr-xr-x 1 root root    0 Jun 10 09:47 test

    -rw——- 1 root root 248K Jun  8 18:01 yum_save_tx.2021-06-08.18-01.yIzI_S.yumtx

    -rw——- 1 root root 256K Jun  8 17:08 yum_save_tx.2021-06-08.17-08.qKUX5n.yumtx

    -rwx—— 1 root root  836 Jan 29  2019 ks-script-QveTmi

    -rwx—— 1 root root 4.7K Jan 29  2019 ks-script-5qnQJp

    -rw——- 1 root root    0 Jan 29  2019 yum.log

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

        # du 估计文件空间使用情况

            -s (summarize,显示总计情况)

            -h(显示大小)

        [root@Daniel-R480 tmp]# du

        0   ./.font-unix

        0   ./.ICE-unix

        0   ./.Test-unix

        0   ./.X11-unix

        0   ./.XIM-unix

        516 .

        [root@Daniel-R480 tmp]# du -h

        0   ./.font-unix

        0   ./.ICE-unix

        0   ./.Test-unix

        0   ./.X11-unix

        0   ./.XIM-unix

        516K    .

        [root@Daniel-R480 tmp]# du -s

        516 .

        [root@Daniel-R480 tmp]# du -sh

        516K    .

        [root@Daniel-R480 tmp]# 

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

        变量:内存空间,有名称

        变量赋值:

        变量替换

作业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)

        编译:将源代码编译成可以在对应的硬件平台上安装运行的版本

        C程序

             Tom,在AMD上编译

            Jerry在intel上编译

        RedHat: 通用格式

            奔腾:

        性能配置最好的状态,在本机上编译,进行安装

4、date,cal,hwclock,man命令详解

4.1 时间管理

4.1.1 date

       时间管理(系统时间)

            Linux: rtc(硬件时间,实时时钟)

         ntp:网络时间协议,网络时间服务器

    硬件时钟:系统硬件自动运行的时间

    系统时钟:操作系统开机以后会自动计算出来接下来经过的时间

练习:

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

    [root@Daniel-R480 ~]# date

    Mon Jun 28 14:40:18 CST 2021

    [root@Daniel-R480 ~]# date +%y

    21

    [root@Daniel-R480 ~]# date +%m

    06

    [root@Daniel-R480 ~]# date +%d

    28

    [root@Daniel-R480 ~]# date +%s

    1624862439

    [root@Daniel-R480 ~]#

4.1.2 hwclock

显示硬件时钟

    hwclock

        -w: 设置硬件时钟为系统时钟

        -s: 设置系统时钟为硬件时钟

    [root@Daniel-SHSH ~]# hwclock

    Mon 28 Jun 2021 02:42:43 PM CST  -0.885496 seconds

    [root@Daniel-SHSH ~]# hwclock -w

    [root@Daniel-SHSH ~]# hwclock -s

3、cal

    日历

    cal: calendar

    后面可加年份,月份

    cal 6 2021

    [root@Daniel-SHSH ~]# cal

          June 2021     

    Su Mo Tu We Th Fr Sa

           1  2  3  4  5

     6  7  8  9 10 11 12

    13 14 15 16 17 18 19

    20 21 22 23 24 25 26

    27 28 29 30

    [root@Daniel-SHSH ~]# cal 3 2021

         March 2021     

    Su Mo Tu We Th Fr Sa

        1  2  3  4  5  6

     7  8  9 10 11 12 13

    14 15 16 17 18 19 20

    21 22 23 24 25 26 27

    28 29 30 31

    [root@Daniel-SHSH ~]# 

4.2 命令帮助

4.2.1 内部命令:

    help COMMAND

    [root@Daniel-SHSH ~]# help cd

    cd: cd [-L|[-P [-e]]] [dir]

        Change the shell working directory.

        Change the current directory to DIR.  The default DIR is the value of the

        HOME shell variable

4.2.2 外部命令:

    COMMAND –help

    [root@Daniel-SHSH ~]# ls –help

    Usage: ls [OPTION]… [FILE]…

    List information about the FILEs (the current directory by default).

    Sort entries alphabetically if none of -cftuvSUX nor –sort is specified.

4.2.3 命令手册(几乎所有命令都有):manual

          1、man COMMAND

                    查看用户手册

          2、whatis COMMAND

               查看命令出现的章节

          3、MAN分章节:

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

            (2)系统调用

            (3)库用户

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

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

            (6)游戏

            (7)杂项(Miscellaneous)

            (8)管理命令(/sbin, /usr/sbin, /usr/local/sbin,需要管理员权限才能使用)

          4、注释符含义

                  <>:必选

                    []:可选

                   …:可以出现多次

                     |:多选一

                     {}:分组

            5、MAN的输出内容

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

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

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

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

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

            BUGS:

            EXAMPLES:使用示例

            SEE ALSO:另外参照

      6、一些基本操作

             (1) 翻屏

                    向后翻一屏:SPACE

                    向前翻一屏:b

                    向后翻一行:ENTER

                    向前翻一行:k

             (2)查找

                               /KEYWORD: 向后

                                n: 下一个

                                N:前一个 

                               ?KEYWORD:向前

                               q: 退出

             (3)在线文档

                               info COMMAND

             (4)文档

                       /usr/share/doc

                    首选文档: 一般软件或者项目都有着官方在线说明,

                                      比如apache, hadoop

练习:

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

                 [root@Daniel-R480 ~]# help echo

                 echo: echo [-neE] [arg …]

                             Write arguments to the standard output.

               2、其作用?

                  Write arguments to the standard output.

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

                        echo -e “This year is 2013.\nToday is 26.”

\转义符

转义,逃逸

练习:

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

               [root@Daniel-R480 ~]# help printf

                     printf: printf [-v var] format [arguments]

                            Formats and prints ARGUMENTS under control of the FORMAT.

              2、其作用?

                  Formats and prints ARGUMENTS under control of the FORMAT.

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

                       printf “The year is 2013.\nToday is 26.\n”