磁盘管理 文件系统管理 重新创建文件系统会损坏原有文件 mkfs: make file system -t FSTYPE mkfs -t ext2 = mkfs.ext2 mkfs -t ext3 = mkfs.ext3 专门管理ext系列文件: mke2fs -j: 创建ext3类型文件系统 -b BLOCK_SIZE: 指定块大小,默认为4096;可用取值为1024、2048或4096; -L LABEL:指定分区卷标; -m #: 指定预留给超级用户的块数百分比 -i #: 用于指定为多少字节的空间创建一个inode,默认为8192;这里给出的数值应该为块大小的2^n倍; -N #: 指定inode个数; -F: 强制创建文件系统; -E: 用户指定额外文件系统属性; blkid: 查询或查看磁盘设备的相关属性 UUID TYPE LABEL e2label: 用于查看或定义卷标 e2label 设备文件 卷标: 设定卷标 tune2fs: 调整文件系统的相关属性 -j: 不损害原有数据,将ext2升级为ext3; -L LABEL: 设定或修改卷标; -m #: 调整预留百分比; -r #: 指定预留块数; -o: 设定默认挂载选项; acl -c #:指定挂载次数达到#次之后进行自检,0或-1表关闭此功能; -i #: 每挂载使用多少天后进行自检;0或-1表示关闭此功能; -l: 显示超级块中的信息; dumpe2fs: 显示文件属性信息 -h: 只显示超级块中的信息 fsck: 检查并修复Linux文件系统 -t FSTYPE: 指定文件系统类型 -a: 自动修复 e2fsck: 专用于修复ext2/ext3文件系统 -f: 强制检查; -p: 自动修复; 挂载:将新的文件系统关联至当前根文件系统 卸载:将某文件系统与当前根文件系统的关联关系预以移除; mount:挂载 mount 设备 挂载点 设备: 设备文件:/dev/sda5 卷标:LABEL=“” UUID: UUID=“” 挂载点:目录 要求: 1、此目录没有被其它进程使用; 2、目录得事先存在; 3、目录中的原有的文件将会暂时隐藏; mount: 显示当前系统已经挂载的设备及挂载点 mount [options] [-o options] DEVICE MOUNT_POINT -a: 表示挂载/etc/fstab文件中定义的所有文件系统 -n: 默认情况下,mount命令每挂载一个设备,都会把挂载的设备信息保存至/etc/mtab文件;使用—n选项意味着挂载设备时,不把信息写入此文件; -t FSTYPE: 指定正在挂载设备上的文件系统的类型;不使用此选项时,mount会调用blkid命令获取对应文件系统的类型; -r: 只读挂载,挂载光盘时常用此选项 -w: 读写挂载 -o: 指定额外的挂载选项,也即指定文件系统启用的属性; remount: 重新挂载当前文件系统 ro: 挂载为只读 rw: 读写挂载 挂载完成后,要通过挂载点访问对应文件系统上的文件; umount: 卸载某文件系统 umount 设备 umount 挂载点 卸载注意事项: 挂载的设备没有进程使用; 练习: 1、创建一个2G的分区,文件系统为ext2,卷标为DATA,块大小为1024,预留管理空间为磁盘分区的8%;挂载至/backup目录,要求使用卷标进行挂载,且在挂载时启动此文件系统上的acl功能; # mke2fs -L DATA -b 1024 -m 8 /dev/sda7 # mount -o acl LABEL=DATA /backup # tune2fs -o acl /dev/sda7 # mount LABEL=DATA /backup 2、将此文件系统的超级块中的信息中包含了block和inode的行保存至/tmp/partition.txt中; # tune2fs -l | egrep -i "block|inode" >> /tmp/partition.txt # dumpe2fs -h | 3、复制/etc目录中的所有文件至此文件系统;而后调整此文件系统类型为ext3,要求不能损坏已经复制而来的文件; # cp -r /etc/* /backup # tune2 -j /dev/sda7 4、调整其预留百分比为3%; # tune2fs -m 3 -L DATA /dev/sda7 5、以重新挂载的方式挂载此文件系统为不更新访问时间戳,并验正其效果; # stat /backup/inittab # cat /backup/inittab # stat # mount -o remount,noatime /backup # cat # stat 6、对此文件系统强行做一次检测; e2fsck -f /dev/sda7 7、删除复制而来的所有文件,并将此文件系统重新挂载为同步(sync);而后再次复制/etc目录中的所有文件至此挂载点,体验其性能变化; # rm -rf /backup/* # mount -o remount,sync /backup # cp -r /etc/* /backup swap分区: free -m fdisk命令中,调整分区类型为82; 创建交换分区: mkswap /dev/sda8 -L LABEL swapon /dev/sda8 -a:启用所有的定义在/etc/fstab文件中的交换设备 swapoff /dev/sda8 回环设备 loopback, 使用软件来模拟实现硬件 创建一个镜像文件,120G dd命令: if=数据来源 of=数据存储目标 bs=1 count=2 seek=#: 创建数据文件时,跳过的空间大小; 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 dd if=/dev/zero of=/var/swapfile bs=1M count=1024 /dev/null mount命令,可以挂载iso镜像; mount DEVICE MOUNT_POINT -o loop: 挂载本地回环设备 wget ftp://172.16.0.1/pub/isos/rhci-5.8-1.iso mount /dev/sda5 /mnt/test 文件系统的配置文件/etc/fstab OS在初始时,会自动挂载此文件中定义的每个文件系统 要挂载的设备 挂载点 文件系统类型 挂载选项 转储频率(每多少天做一次完全备份) 文件系统检测次序(只有根可以为1) /dev/sda5 /mnt/test ext3 defaults 0 0 mount -a:挂载/etc/fstab文件中定义的所有文件系统 fuser: 验正进程正在使用的文件或套接字文件 -v: 查看某文件上正在运行的进程 -k: -m fuser -km MOUNT_POINT:终止正在访问此挂载点的所有进程 练习: 1、创建一个5G的分区,文件系统为ext3,卷标为MYDATA,块大小为1024,预留管理空间为磁盘分区的3%,要求开机后可以自动挂载至/data目录,并且自动挂载的设备要使用卷标进行引用; 2、创建一个本地回环文件/var/swaptemp/swapfile来用于swap,要求大小为512MB,卷标为SWAP-FILE,且开机自动启用此交换设备; # mkdir /var/swaptemp # dd if=/dev/zero of=/var/swaptemp/swapfile bs=1M count=512 # mkswap LABLE=SWAP-FILE /var/swaptemp/swapfile /etc/fstab /var/swaptemp/swapfile swap swap defaults 0 0 3、上述第一问,如何让其自动挂载的同时启用ACL功能; /etc/fstab LABEL='MYDATA' /data ext3 defaults,acl 0 0 压缩、解压缩命令 压缩格式:gz, bz2, xz, zip, Z 压缩算法:算法不同,压缩比也会不同; compress: FILENAME.Z uncompress gzip: .gz gzip /PATH/TO/SOMEFILE:压缩完成后会删除原文件 -d: -#:1-9,指定压缩比,默认是6; gunzip: gunzip /PATH/TO/SOMEFILE.gz: 解压完成后会删除原文件 zcat /PATH/TO/SOMEFILE.gz: 不解压的情况,查看文本文件的内容 bzip2: .bz2 比gzip有着更大压缩比的压缩工具,使用格式近似 bzip2 /PATH/TO/SOMEFILE -d -#: 1-9,默认是6 -k: 压缩时保留原文件 bunzip2 /PATH/TO/SOMEFILE.bz2 bzcat xz: .xz xz /PATH/TO/SOMEFILE -d -#: 1-9, 默认是6 -k: 压缩时保留原文件 unxz xzdec xzcat zip: 既归档又压缩的工具 zip FILENAME.zip FILE1 FILE2 ...: 压缩后不删除原文件 unzip FILENAME.zip archive: 归档,归档本身并不意味着压缩 xz, bz2, gz tar: 归档工具, .tar -c: 创建归档文件 -f FILE.tar: 操作的归档文件 -x: 展开归档 --xattrs: 归档时,保留文件的扩展属性信息 -t: 不展开归档,直接查看归档了哪些文件 -zcf: 归档并调用gzip压缩 -zxf: 调用gzip解压缩并展开归档,-z选项可省略 -jcf: bzip2 -jxf: -Jcf: xz -Jxf: cpio: 归档工具 练习:写一个脚本 从键盘让用户输入几个文件,脚本能够将此几个文件归档压缩成一个文件; read: -p “PROMPT": 给出提示 脚本编程: 顺序结构 选择结构 if case 循环结构 for while until while循环:适用于循环次数未知的场景,要有退出条件 语法: while CONDITION; do statement ... done 计算100以内所有正整数的和 #!/bin/bash declare -i I=1 declare -i SUM=0 while [ $I -le 100 ]; do let SUM+=$I let I++ done echo $SUM 练习:转换用户输入的字符为大写,除了quit: #!/bin/bash # read -p "Input something: " STRING while [ $STRING != 'quit' ]; do echo $STRING | tr 'a-z' 'A-Z' read -p "Input something: " STRING done 练习:每隔5秒查看hadoop用户是否登录,如果登录,显示其登录并退出;否则,显示当前时间,并说明hadoop尚未登录: #!/bin/bash # who | grep "hadoop" &> /dev/null RETVAL=$? while [ $RETVAL -ne 0 ]; do echo "`date`, hadoop is not log." sleep 5 who | grep "hadoop" &> /dev/null RETVAL=$? done echo "hadoop is logged in." 写一个脚本: 1) 显示一个菜单给用户: d|D) show disk usages. m|M) show memory usages. s|S) show swap usages. *) quit. 2) 当用户给定选项后显示相应的内容; 扩展: 当用户选择完成,显示相应信息后,不退出;而让用户再一次选择,再次显示相应内容;除了用户使用quit; #!/bin/bash # cat << EOF d|D) show disk usages. m|M) show memory usages. s|S) show swap usages. *) quit. EOF read -p "Your choice: " CHOICE while [ $CHOICE != 'quit' ];do case $CHOICE in d|D) echo "Disk usage: " df -Ph ;; m|M) echo "Memory usage: " free -m | grep "Mem" ;; s|S) echo "Swap usage: " free -m | grep "Swap" ;; *) echo "Unknown.." ;; esac read -p "Again, your choice: " CHOICE done ext2: 文件系统块组组成: 超级块、GDT、block bitmap、inode bitmap、data blocks 文件系统挂载时的注意事项: 1、挂载点事先存在; 2、目录是否已经被其它进程使用; 3、目录中的原有文件会被暂时隐藏; mount DEVICE MOUNT_POINT 1、设备文件; 2、LABEL 3、UUID /etc/fstab文件格式: 设备 挂载点 文件系统类型 挂载选项 转储频率 检测次序 tune2fs -l -L -o dumpe2fs -h 安装RHEL6.3 x86_64的方法(前提:请确保你的CPU支持硬件虚拟化技术): 1、创建虚拟机; 2、下载isos目录中的rhci-rhel-6.3-1.iso,并导入虚拟机的虚拟光驱; 3、在boot提示符输入:linux ip=172.16.x.1 netmask=255.255.0.0 gateway=172.16.0.1 dns=172.16.0.1 ks=http://172.16.0.1/rhel6.cfg 64, 32 /lib /lib64 RAID: 级别:仅代表磁盘组织方式不同,没有上下之分; 0: 条带 性能提升: 读,写 冗余能力(容错能力): 无 空间利用率:nS 至少2块盘 1: 镜像 性能表现:写性能下降,读性能提升 冗余能力:有 空间利用率:1/2 至少2块盘 2 3 4: 5: 性能表现:读,写提升 冗余能力:有 空间利用率:(n-1)/n 至少需要3块 10: 性能表现:读、写提升 冗余能力:有 空间利用率:1/2 至少需要4块 01: 性能表现:读、写提升 冗余能力:有 空间利用率:1/2 至少需要4块 50: 性能表现:读、写提升 冗余能力:有 空间利用率:(n-2)/n 至少需要6块 jbod: 性能表现:无提升 冗余能力:无 空间利用率:100% 至少需要2块 逻辑RIAD: /dev/md0 /dev/md1 md: mdadm: 将任何块设备做成RAID 模式化的命令: 创建模式 -C 专用选项: -l: 级别 -n #: 设备个数 -a {yes|no}: 是否自动为其创建设备文件 -c: CHUNK大小, 2^n,默认为64K -x #: 指定空闲盘个数 管理模式 --add, --remove, --fail mdadm /dev/md# --fail /dev/sda7 监控模式 -F 增长模式 -G 装配模式 -A 查看RAID阵列的详细信息 mdadm -D /dev/md# --detail 停止阵列: mdadm -S /dev/md# --stop 创建一个空间大小为10G的RAID5设备;其chuck大小为32k;要求此设备开机时可以自动挂载至/backup目录; RAID0 2G: 4: 512MB 2: 1G RAID1 2G 2:2G watch: 周期性地执行指定命令,并以全屏方式显示结果 -n #:指定周期长度,单位为秒,默认为2 格式: watch -n # 'COMMAND' 将当前RAID信息保存至配置文件,以便以后进行装配: mdamd -D --scan > /etc/mdadm.conf RAID5: 2G: 3, 1G 归档 --xattrs 文件系统类型: ext2 ext3 cat /proc/filesystems : 查看当前内核所支持文件系统类型 RAID: 独立冗余磁盘阵列 Linux:硬件,软件 /dev/md# MD: Multi Device, 多设备 mdadm:用户空间工具,管理工具 创建 -C 管理 --add, --remove, --fail -a, -r, -f 监控 增长 装配 -A -S -D RAID0, RAID1 RAID01, RAID10 RAID0+1: MD, DM /dev/md# meta device DM: Device Mapper 逻辑设备 RAID, LVM2 DM: LVM2 快照 多路径 任务计划 10G, VG vgcreate VG_NAME /PATH/TO/PV -s #: PE大小,默认为4MB lvcreate -n LV_NAME -L #G VG_NAME 练习:创建一个由两个物理卷组成的大小为20G的卷组myvg,要求其PE大小为16M;而后在此卷组中创建一个大小为5G的逻辑卷lv1,此逻辑卷要能在开机后自动挂载至/users目录,且支持ACL功能; 缩减前面创建的逻辑卷lv1的大小至2G; 一、扩展逻辑卷; lvextend -L [+]# /PATH/TO/LV 2G, +3G 5G resize2fs resize2fs -p /PATH/TO/LV 二、缩减逻辑卷; 注意:1、不能在线缩减,得先卸载; 2、确保缩减后的空间大小依然能存储原有的所有数据; 3、在缩减之前应该先强行检查文件,以确保文件系统处于一至性状态; df -lh umount e2fsck -f resize2fs resize2fs /PATH/TO/PV 3G lvreduce -L [-]# /PATH/TO/LV 重新挂载 三、快照卷 1、生命周期为整个数据时长;在这段时长内,数据的增长量不能超出快照卷大小; 2、快照卷应该是只读的; 3、跟原卷在同一卷组内; lvcreate -s -p r|w lvcreate -L # -n SLV_NAME -p r /PATH/TO/LV 脚本编程控制结构: 顺序 选择 if case 循环 for while until while CONDITION; do statment done 进入循环:条件满足 退出循环:条件不满足 until CONDITION; do statement ... done 进入循环:条件不满足 退出循环:条件满足 for 变量 in 列表; do 循环体 done for (( expr1 ; expr2 ; expr3 )); do 循环体 done 写一个脚本: 1、通过ping命令测试192.168.0.151到192.168.0.254之间的所有主机是否在线, 如果在线,就显示"ip is up.",其中的IP要换为真正的IP地址,且以绿色显示; 如果不在线,就显示"ip is down.",其中的IP要换为真正的IP地址,且以红色显示; 要求:分别使用while,until和for(两种形式)循环实现。 ping -c -W awk 'PATTERN{ACTION}' file print $1 写一个脚本(前提:请为虚拟机新增一块硬盘,假设它为/dev/sdb),为指定的硬盘创建分区: 1、列出当前系统上所有的磁盘,让用户选择,如果选择quit则退出脚本;如果用户选择错误,就让用户重新选择; 2、当用户选择后,提醒用户确认接下来的操作可能会损坏数据,并请用户确认;如果用户选择y就继续,n就退出;否则,让用户重新选择; 3、抹除那块硬盘上的所有分区(提示,抹除所有分区后执行sync命令,并让脚本睡眠3秒钟后再分区);并为其创建三个主分区,第一个为20M,第二个为512M, 第三个为128M,且第三个为swap分区类型;(提示:将分区命令通过echo传送给fdisk即可实现) fdisk -l |grep " dd if=/dev/zero of=/dev/sdb bs=512 count=1 sync sleep 3 RAID LVM: 逻辑卷的缩减 扩展 快照卷 while CONDITION; do 循环体 done while [ $VAR != 'quit' ];do done 网络及网络配置 0000 0001 . 0000 0001 1111 1111 . 0000 0000 0000 0001 . 0000 0010 0000 0001 . 0000 0000 1.0 1.1 --> 2.1 1.0 1.1 --> 1.2 1.0 1.0 IPv4点分十进制: 0000 0000 - 1111 1111 0-255 221.34.23.12 网络地址: 主机地址: 32位二进制 A类: 255.0.0.0, 8: 0 000 0001 - 0 111 1111 127个A类,127用于回环,1-126 2^7-1个A类 容纳多少个主机:2^24-2 主机位全0:网络地址 主机位全1:广播地址 B类:255.255.0.0, 16 10 00 0000- 10 11 1111 128-191 129.1.0.0. 130.1.0.0 64个B类,2^14个B类网 容纳多少个主机:2^16-2 C类:255.255.255.0, 24 110 0 0000 - 110 1 1111 192-223 32个C类, 2^21个C类网 容纳多个少个主机:2^8-2 私有地址: A类:10.0.0.0/8 B类:172.16.0.0/16-172.31.0.0/16 C类:192.168.0.0/24-192.168.255.0/24 路由:选路 ICANN, IANA D类: 1110 0000 - 1110 1111 224-239 E类: 主机接入网络: IP NETMASK GATEWAY HOSTNAME DNS1 DNS2 DNS3 手动指定 DHCP:Dynamic Host Configuration Protocol 169.254. 路由 Linux: 网络属于内核的功能 RHEL5: /etc/modprobe.conf alias RHEL6: /etc/udev/rules.d/70-persistent-net.rules 以太网:ethX ifconfig [ethX] -a: 显示所有接口的配置住处 ifconfig ethX IP/MASK [up|down] 配置的地址立即生效,但重启网络服务或主机,都会失效; 网络服务: RHEL5: /etc/init.d/network {start|stop|restart|status} RHEL6: /etc/init.d/NetworkManager {start|stop|restart|status} 网关: route add: 添加 -host: 主机路由 -net:网络路由 -net 0.0.0.0 route add -net|-host DEST gw NEXTHOP route add default gw NEXTHOP del:删除 -host -net route del -net 10.0.0.0/8 route del -net 0.0.0.0 route del default 所做出的改动重启网络服务或主机后失效; 查看: route -n: 以数字方式显示各主机或端口等相关信息 网络配置文件: /etc/sysconfig/network 网络接口配置文件: /etc/sysconfig/network-scripts/ifcfg-INTERFACE_NAME DEVICE=: 关联的设备名称,要与文件名的后半部“INTERFACE_NAME”保持一致; BOOTPROTO={static|none|dhcp|bootp}: 引导协议;要使用静态地址,使用static或none;dhcp表示使用DHCP服务器获取地址; IPADDR=: IP地址 NETMASK=:子网掩码 GATEWAY=:设定默认网关; ONBOOT=:开机时是否自动激活此网络接口; HWADDR=: 硬件地址,要与硬件中的地址保持一致;可省; USERCTL={yes|no}: 是否允许普通用户控制此接口; PEERDNS={yes|no}: 是否在BOOTPROTO为dhcp时接受由DHCP服务器指定的DNS地址; 不会立即生效,但重启网络服务或主机都会生效; 路由: /etc/sysconfig/network-scripts/route-ethX 添加格式一: DEST via NEXTHOP 添加格式二: ADDRESS0= NETMASK0= GATEWAY0= DNS服务器指定方法只有一种: /etc/resolv.conf nameserver DNS_IP_1 nameserver DNS_IP_2 指定本地解析: /etc/hosts 主机IP 主机名 主机别名 172.16.0.1 www.magedu.com www DNS-->/etc/hosts-->DNS 配置主机名: hostname HOSTNAME 立即生效,但不是永久有效; /etc/sysconfig/network HOSTNAME= RHEL5: setup: system-config-network-tui system-config-network-gui ifconfig, 老旧 iproute2 ip link: 网络接口属性 addr: 协议地址 route: 路由 link show ip -s link show set ip link set DEV {up|down} addr add ip addr add ADDRESS dev DEV del ip addr del ADDRESS dev DEV show ip addr show dev DEV to PREFIX flush ip addr flush dev DEV to PREFIX 一块网卡可以使用多个地址: 网络设备可以别名: eth0 ethX:X, eth0:0, eth0:1, ... 配置方法: ifconfig ethX:X IP/NETMASK /etc/sysconfig/network-scripts/ifcfg-ethX:X DEVICE=ethX:X 非主要地址不能使用DHCP动态获取; ip eth1, 添加个地址192.168.100.1 ip addr add 192.168.100.1/24 dev eth1 label eth1:0 primary address secondary adress 192.168.100.6 10.0.1.0/24, 192.168.100.6 路由: route add -net 10.0.1.0/24 gw 192.168.100.6 ip route add to 10.0.1.0/24 dev eth1 via 192.168.100.6 add, change, show, flush, replace ifconfig eth0, 172.16.200.33/16 ifconfig eth0:0 172.16.200.33/16 TCP: URG SYN ACK PSH RST FIN 软件包管理 应用程序: 程序,Architecture C语言:源代码-->(编译)二进制格式 脚本:解释器(二进制程序) 源代码-->编译-->链接-->运行 程序: 库 静态 动态 静态链接 动态链接 共享库 配置文件: dir=/path/to/somewhere 程序组成部分: 二进制程序 库 配置文件 帮助文件 /boot /etc /usr /var /dev /lib /tmp /bin /sbin /proc /sys /mnt /media /home /root /misc /opt /srv /usr/share/man /etc, /bin, /sbin, /lib 系统启动就需要用到的程序,这些目录不能挂载额外的分区,必须在根文件系统的分区上 /usr/ bin sbin lib 操作系统核心功能,可以单独分区 /usr/local bin sbin lib etc man /opt /proc /sys 不能单独分区,默认为空; /dev: 设备,不能单独分区; udev /root: 不能单独分区 /var:建议单独分区 /boot:内核,initrd(initramfs) 内核: POST-->BIOS(HD)-->(MBR)bootloader(文件系统结构,ext2, ext3, xfs)-->内核 程序:指令+数据 指令:芯片 CPU: 普通指令,特权指令 指令集 C语言: Powerpc: 二进制格式 x86: x86: 汇编 powerpc: 汇编 高级语言: C: 软件包管理器的核心功能: 1、制作软件包; 2、安装、卸载、升级、查询、校验; Redhat, SUSE, Debian Redhat, SUSE: RPM Redhat Package Manager PRM is Package Manager Debian: dpt 依赖关系: X-->Y-->Z X-->Y-->Z 前端工具:yum, apt-get 后端工具:RPM, dpt yum: Yellowdog Update Modifier yum rpm命令: rpm: 数据库:/var/lib/rpm rpmbuild: 安装、查询、卸载、升级、校验、数据库的重建、验正数据包等工作; rpm命名: 包:组成部分 主包: bind-9.7.1-1.el5.i586.rpm 子包: bind-libs-9.7.1-1.el5.i586.rpm bind-utils-9.7.1-1.el5.i586.rpm 包名格式: name-version-release.arch.rpm bind-major.minor.release-release.arch.rpm 主版本号:重大改进 次版本号:某个子功能发生重大变化 发行号:修正了部分bug,调整了一点功能 bind-9.7.1.tar.gz rpm包: 二进制格式 rpm包作者下载源程序,编译配置完成后,制作成rpm包 bind-9.7.1-1.noarch.rpm bind-9.7.1-1.ppc.rpm rpm: 1、安装 rpm -i /PATH/TO/PACKAGE_FILE -h: 以#显示进度;每个#表示2%; -v: 显示详细过程 -vv: 更详细的过程 rpm -ivh /PATH/TO/PACKAGE_FILE --nodeps: 忽略依赖关系; --replacepkgs: 重新安装,替换原有安装; --force: 强行安装,可以实现重装或降级; 2、查询 rpm -q PACKAGE_NAME: 查询指定的包是否已经安装 rpm -qa : 查询已经安装的所有包 rpm -qi PACKAGE_NAME: 查询指定包的说明信息; rpm -ql PACKAGE_NAME: 查询指定包安装后生成的文件列表; rpm -qc PACEAGE_NEME:查询指定包安装的配置文件; rpm -qd PACKAGE_NAME: 查询指定包安装的帮助文件; rpm -q --scripts PACKAGE_NAME: 查询指定包中包含的脚本 rpm -qf /path/to/somefile: 查询指定的文件是由哪个rpm包安装生成的; 如果某rpm包尚未安装,我们需查询其说明信息、安装以后会生成的文件; rpm -qpi /PATH/TO/PACKAGE_FILE rpm -qpl 3、升级 rpm -Uvh /PATH/TO/NEW_PACKAGE_FILE: 如果装有老版本的,则升级;否则,则安装; rpm -Fvh /PATH/TO/NEW_PACKAGE_FILE:如果装有老版本的,则升级;否则,退出; --oldpackage: 降级 4、卸载 rpm -e PACKAGE_NAME --nodeps 5、校验 rpm -V PACKAGE_NAME 6、重建数据库 rpm --rebuilddb: 重建数据库,一定会重新建立; --initdb:初始化数据库,没有才建立,有就不用建立; 7、检验来源合法性,及软件包完整性; 加密类型: 对称:加密解密使用同一个密钥 公钥:一对儿密钥,公钥,私钥;公钥隐含于私钥中,可以提取出来,并公开出去; 单向: # ls /etc/pki/rpm-gpg/ RPM-GPG-KEY-redhat-release rpm -K /PAPT/TO/PACKAGE_FILE dsa, gpg: 验正来源合法性,也即验正签名;可以使用--nosignature,略过此项 sha1, md5: 验正软件包完整性;可以使用--nodigest,略过此项 rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release: 导入密钥文件 1、rpm -qf 2、rpm -qpl l: List i: 软件包的信息; 3、--import /etc/pki/rpm-gpg/ 4、--rebuilddb rpm --> yum HTML: HyperText Mark Language XML: eXtended Mark Language XML, JSON: 半结构化的数据 yum仓库中的元数据文件: primary.xml.gz 所有RPM包的列表; 依赖关系; 每个RPM安装生成的文件列表; filelists.xml.gz 当前仓库中所有RPM包的所有文件列表; other.xml.gz 额外信息,RPM包的修改日志; repomd.xml 记录的是上面三个文件的时间戳和校验和; yum install zsh comps*.xml: RPM包分组信息 ftp://172.16.0.1/pub/{Server,VT,Cluster,ClusterStorage} 如何为yum定义repo文件 [Repo_ID] name=Description baseurl= ftp:// http:// file:/// enabled={1|0} gpgcheck={1|0} gpgkey= yum [options] [command] [package ...] -y: 自动回答为yes --nogpgcheck list: 列表 支持glob all available:可用的,仓库中有但尚未安装的 installed: 已经安装的 updates: 可用的升级 clean: 清理缓存 [ packages | headers | metadata | dbcache | all ] repolist: 显示repo列表及其简要信息 all enabled: 默认 disabled install: 安装 yum install PACKAGE_NAME update: 升级 update_to: 升级为指定版本 remove|erase:卸载 info: provides| whatprovides: 查看指定的文件或特性是由哪个包安装生成的; groupinfo grouplist groupinstall groupremove groupupdate /media/cdrom/{Server,VT,Cluster,ClusterStorage} 如何创建yum仓库: createrepo http://172.16.0.1/yum/{Server,VT} 练习: 1、将系统安装光盘挂载至/media/yum目录,用其实现yum仓库; 2、配置使用http://172.16.0.1/yum/{Server,VT,Cluster,ClusterStorage}为可用yum仓库; 写一个脚本,完成以下功能: 说明:此脚本能于同一个repo文件中创建多个Yum源的指向; 1、接受一个文件名做为参数,此文件存放至/etc/yum.repos.d目录中,且文件名以.repo为后缀;要求,此文件不能事先存,否则,报错; 2、在脚本中,提醒用户输入repo id;如果为quit,则退出脚本;否则,继续完成下面的步骤; 3、repo name以及baseurl的路径,而后以repo文件的格式将其保存至指定的文件中; 4、enabled默认为1,而gpgcheck默认设定为0; 5、此脚本会循环执行多次,除非用户为repo id指定为quit; if [ -e $1 ]; then echo "$1 exist." exit 5 fi [repo id] name= baseurl= enabled= gpgcheck= while, until, for break: 提前退出循环 continue:提前结束本轮循环,而进入下一轮循环; 1000, SUM>5000 while的特殊用法一: while :;do done while的特殊用法二: while read LINE; do done < /PATH/TO/SOMEFILE /etc/passwd 写一个脚本,完成如下功能: 说明:此脚本能够为指定网卡创建别名,则指定地址;使用格式如:mkethalias.sh -v|--verbose -i ethX 1、-i选项用于指定网卡;指定完成后,要判断其是否存在,如果不存在,就退出; 2、如果用户指定的网卡存在,则让用户为其指定一个别名,此别名可以为空;如果不空,请确保其事先不存在,否则,要报错,并让用户重新输入; 3、在用户输入了一个正确的别名后,请用户输入地址和掩码;并将其配置在指定的别名上; 4、如果用户使用了-v选项,则在配置完成后,显示其配置结果信息;否则,将不显示; RPM安装: 二进制格式: 源程序-->编译-->二进制格式 有些特性是编译选定的,如果编译未选定此特性,将无法使用; rpm包的版本会落后于源码包,甚至落后很多;bind-9.8.7, bind-9.7.2 定制:手动编译安装 编译环境,开发环境 开发库,开发工具 Linux: C, GNU: C C,C++: gcc: GNU C Complier, C g++: make: 项目管理工具, makefile: 定义了make(gcc,g++)按何种次序去编译这些源程序文件中的源程序 automake, --> makefile.in --> makefile autoconf, --> configure 100个可选择特性, make install 编译安装的三步骤: 前提:准备开发环境(编译环境) 安装"Development Tools"和"Development Libraries" # tar # cd # ./configure --help --prefix=/path/to/somewhere --sysconfdir=/PATH/TO/CONFFILE_PATH 功能:1、让用户选定编译特性;2、检查编译环境; # make # make install # tar xf tengine-1.4.2.tar.gz # cd tegnine-1.4.2 # ./configure --prefix=/usr/local/tengine --conf-path=/etc/tengine/tengine.conf # make # make install # /usr/local/tengine/sbin/nginx 1、修改PATH环境变量,以能够识别此程序的二进制文件路径; 修改/etc/profile文件 在/etc/profile.d/目录建立一个以.sh为名称后缀的文件,在里面定义export PATH=$PATH:/path/to/somewhere 2、默认情况下,系统搜索库文件的路径/lib, /usr/lib; 要增添额外搜寻路径: 在/etc/ld.so.conf.d/中创建以.conf为后缀名的文件,而后把要增添的路径直接写至此文件中; # ldconfig 通知系统重新搜寻库文件 -v: 显示重新搜寻库的过程 3、头文件:输出给系统 默认:/usr/include 增添头文件搜寻路径,使用链接进行: /usr/local/tengine/include/ /usr/include/ 两种方式: ln -s /usr/local/tengine/include/* /usr/include/ 或 ln -s /usr/local/tengine/include /usr/include/tengine 4、man文件路径:安装在--prefix指定的目录下的man目录;/usr/share/man 1、man -M /PATH/TO/MAN_DIR COMMAND 2、在/etc/man.config中添加一条MANPATH netstat命令: -r: 显示路由表 -n: 以数字方式显示 -t: 建立的tcp连接 -u: 显示udp连接 -l: 显示监听状态的连接 -p: 显示监听指定的套接字的进程的进程号及进程名 循环控制: break 中断循环,而后执行循环后面的语句; continue 中断当前这一次循环,提前进入下一软循环 写一个脚本,完成以下功能: 1、提示用户输入一个用户名; 2、显示一个菜单给用户,形如: U|u show UID G|g show GID S|s show SHELL Q|q quit 3、提醒用户选择一个选项,并显示其所选择的内容; 如果用户给的是一个非上述所提示的选项,则提醒用户给出的选项错误,并请其重新选择后执行; 写一个脚本: 1、判断一个指定的bash脚本是否有语法错误;如果有错误,则提醒用户键入Q或者q无视错误并退出,其它任何键可以通过vim打开这个指定的脚本; 2、如果用户通过vim打开编辑后保存退出时仍然有错误,则重复第1步中的内容;否则,就正常关闭退出。 ./syntax.sh a.sh until bash -n $1 &> /dev/null; do read -p "Syntax error, [Qq] to quit, others for editing: " CHOICE case $CHOICE in q|Q) echo "Something wrong, quiting." exit 5 ;; *) vim + $1 ;; esac done echo "0K" 函数:功能, function 代码重用: 库:so 脚本编程之函数: function: 功能 结构化编程,不能独立运行,需要调用时执行,可以被多次调用 定义一个函数: function FUNCNAME { command } FUNCNAME() { command } 自定义执行状态返回值: return # 0-255 接受参数的函数: ./a.sh m n $1: m $2: n TWOINT 5 6 $1: 5 $2: 6 练习:写一个脚本,判定192.168.0.200-192.168.0.254之间的主机哪些在线。要求: 1、使用函数来实现一台主机的判定过程; 2、在主程序中来调用此函数判定指定范围内的所有主机的在线情况。 #!/bin/bash # PING() { for I in {200..254};do if ping -c 1 -W 1 192.168.0.$I &> /dev/null; then echo "192.168.0.$I is up." else echo "192.168.0.$I is down." fi done } PING #!/bin/bash # PING() { if ping -c 1 -W 1 $1 &> /dev/null; then echo "$1 is up." else echo "$1 is down." fi } for I in {200..254}; do PING 192.168.0.$I done #!/bin/bash # PING() { if ping -c 1 -W 1 $1 &> /dev/null; then return 0 else return 1 fi } for I in {200..254}; do PING 192.168.0.$I if [ $? -eq 0 ]; then echo "192.168.0.$I is up." else echo "192.168.0.$I is down." fi done 写一个脚本:使用函数完成 1、函数能够接受一个参数,参数为用户名; 判断一个用户是否存在 如果存在,就返回此用户的shell和UID;并返回正常状态值; 如果不存在,就说此用户不存在;并返回错误状态值; 2、在主程序中调用函数; 扩展1:在主程序中,让用户自己输入用户名后,传递给函数来进行判断; 扩展2:在主程序中,输入用户名判断后不退出脚本,而是提示用户继续输入下一个用户名;如果用户输入的用户不存在,请用户重新输入;但如果用户输入的是q或Q就退出; #!/bin/bash # user () { if id $1 &> /dev/null ;then echo "`grep ^$1 /etc/passwd | cut -d: -f3,7`" return 0 else echo "no $1" return 1 fi } read -p "please input username:" username until [ $username == q -o $username == Q ]; do user $username if [ $? == 0 ];then read -p "please input again:" username else read -p "no $username,please input again:" username fi done 函数也可以接受参数, 即可以向函数传递参数 函数接受一个用户名参数,显示此用户的shell和UID; 写一个函数:接受一命令参数ls /bin/ls, /mnt/sysroot/bin/ls /sbin/ifconfig, /mnt/sysroot/sbin/ifconfig 进程及作业管理 Uninterruptible sleep: 不可中断的睡眠 Interruptible sleep:可中断睡眠 kernel: init: COW: Copy On Write, 写时复制 100-139:用户可控制 0-99:内核调整的 O: O(1) O(n) O(logn) O(n^2) O(2^n) init: 进程号为1 ps: Process State SysV风格:- BSD风格: a: 所有与终端有关的进程 u: x: 所有与终端无关的进程 进程的分类: 跟终端相关的进程 跟终端无关的进程 进程状态: D:不可中断的睡眠 R:运行或就绪 S:可中断的睡眠 T:停止 Z:僵死 <:高优先级进程 N: 低优先级进程 +:前台进程组中的进程 l: 多线程进程 s: 会话进程首进程 ps -elF -ef -eF ps -o PROPERTY1,PROPERTY2 ps -o pid,comm,ni pstree: 显示当前系统上的进程树 pgrep: pidof: 根据程序名称,查找其相关进程的ID号; top: vmstat free kill pkill bg fg <:高优先级的进程 N:低优先级的进程 l: 多线程进程 +:前台进程组中的进程 s: 会话进程的领导者 top: M: 根据驻留内存大小进行排序 P:根据CPU使用百分比进行排序 T: 根据累计时间进行排序 l: 是否显示平均负载和启动时间 t: 是否显示进程和CPU状态相关信息 m: 是否显示内存相关信息 c: 是否显示完整的命令行信息 q: 退出top k: 终止某个进程 top -d: 指定延迟时长,单位是秒 -b: 批模式 -n #:在批模式下,共显示多少批 进程间通信(IPC: Inter Process Communication) 共享内存 信号: Signal Semaphore 重要的信号: 1:SIGHUP: 让一个进程不用重启,就可以重读其配置文件,并让新的配置信息生效; 2: SIGINT:Ctrl+c: 中断一个进程 9: SIGKILL:杀死一个进程 15: SIGTERM:终止一个进程, 默认信号 指定一个信号: 信号号码:kill -1 信号名称:kill -SIGKILL 信号名称简写:kill -KILL kill PID killall COMMAND 调整nice值: 调整已经启动的进程的nice值: renice NI PID 在启动时指定nice值: nice -n NI COMMAND 前台作业:占据了命令提示符 后台作业:启动之后,释放命令提示符,后续的操作在后台完成 前台-->后台: Ctrl+z: 把正在前台的作业送往后台 COMMAND &:让命令在后台执行 bg: 让后台的停止作业继续运行 bg [[%]JOBID] jobs: 查看后台的所有作业 作业号,不同于进程号 +:命令将默认操作的作业 -:命令将第二个默认操作的作业 fg: 将后台的作业调回前台 fg [[%]JOBID] kill %JOBID: 终止某作业 vmstat:系统状态查看命令 uptime: /proc/meminfo ./configure: 检查编译环境:编译工具、库、头文件 设定编译安装选项 结果:结果Makefile.in生成makefile make make install 日志系统 Linux系统启动流程 PC: OS(Linux) POST-->BIOS(Boot Sequence)-->MBR(bootloader,446)-->Kernel-->initrd-->(ROOTFS)/sbin/init(/etc/inittab) 启动的服务不同: 运行级别:0-6 0:halt 1: single user mode, 直接以管理员身份切入, s,S,single 2:multi user mode, no NFS 3: multi user mode, text mode 4:reserved 5: multi user mode, graphic mode 6: reboot 详解启动过程 bootloader(MBR) LILO: LInux LOader GRUB: GRand Unified Bootloader Stage1: MBR Stage1_5: Stage2: /boot/grub/ grub.conf default=0 # 设定默认启动的title的编号,从0开始 timeout=5 # 等待用户选择的超时时长,单位是秒 splashimage=(hd0,0)/grub/splash.xpm.gz # grub的背景图片 hiddenmenu # 隐藏菜单 password redhat password --md5 $1$HKXJ51$B9Z8A.X//XA.AtzU1.KuG. title Red Hat Enterprise Linux Server (2.6.18-308.el5) # 内核标题,或操作系统名称,字符串,可自由修改 root (hd0,0) # 内核文件所在的设备;对grub而言,所有类型硬盘一律hd,格式为(hd#,N);hd#, #表示第几个磁盘;最后的N表示对应磁盘的分区; kernel /vmlinuz-2.6.18-308.el5 ro root=/dev/vol0/root rhgb quiet # 内核文件路径,及传递给内核的参数 initrd /initrd-2.6.18-308.el5.img # ramdisk文件路径 password --md5 $1$HKXJ51$B9Z8A.X//XA.AtzU1.KuG. title Install Red Hat Enterprise Linux 5 root (hd0,0) kernel /vmlinuz-5 ks=http://172.16.0.1/workstation.cfg ksdevice=eth0 noipv6 initrd /initrd-5 password --md5 $1$FSUEU/$uhUUc8USBK5QAXc.BfW4m. 查看运行级别: runlevel: who -r 查看内核release号: uname -r 安装grub stage1: # grub grub> root (hd0,0) grub> set (hd0) 安装grub第二种方式: # grub-install --root-directory=/path/to/boot's_parent_dir /PATH/TO/DEVICE grub> find grub> root (hd#,N) grub> kernel /PATH/TO/KERNEL_FILE grub> initrd /PATH/TO/INITRD_FILE grub> boot Kernel初始化的过程: 1、设备探测 2、驱动初始化(可能会从initrd(initramfs)文件中装载驱动模块) 3、以只读挂载根文件系统; 4、装载第一个进程init(PID:1) /sbin/init:(/etc/inittab) upstart: ubuntu, d-bus, event-driven systemd: id:runlevels:action:process id: 标识符 runlevels: 在哪个级别运行此行; action: 在什么情况下执行此行; process: 要运行程序; id:3:initdefault: si::sysinit:/etc/rc.d/rc.sysinit ACTION: initdefault: 设定默认运行级别 sysinit: 系统初始化 wait: 等待级别切换至此级别时执行 respawn: 一旦程序终止,会重新启动 /etc/rc.d/rc.sysinit完成的任务: 1、激活udev和selinux; 2、根据/etc/sysctl.conf文件,来设定内核参数; 3、设定时钟时钟; 4、装载键盘映射; 5、启用交换分区; 6、设置主机名; 7、根文件系统检测,并以读写方式重新挂载; 8、激活RAID和LVM设备; 9、启用磁盘配额; 10、根据/etc/fstab,检查并挂载其它文件系统; 11、清理过期的锁和PID文件; for I in /etc/rc3.d/K*; do $I stop done for I in /etc/rc3.d/S*; do $I start done ##: 关闭或启动的优先次序,数据越小越优先被选定 先关闭以K开头的服务,后启动以S开头的服务; 内核设计风格: RedHat, SUSE 核心:动态加载 内核模块 内核:/lib/modules/“内核版本号命令的目录”/ vmlinuz-2.6.32 /lib/modules/2.6.32/ RedHat5: ramdisk-->initrd RedHat6: ramfs-->initramfs 单内核:Linux (LWP) 核心:ko(kernel object) so() 微内核:Windows, Solaris (线程) chroot: chroot /PATH/TO/TEMPROOT [COMMAND...] chroot /test/virrrot /bin/bash ldd /PATH/TO/BINARY_FILE:显示二进制文件所依赖的共享库 MBR(bootloader)--> Kernel --> initrd(initramfs) --> (ROOTFS) --> /sbin/init(/etc/inittab) /etc/inittab, /etc/init/*.conf upstart init /etc/inittab id:runlevels:action:process id:5:initdefault: si::sysinit:/etc/rc.d/rc.sysinit OS初始化 l0:0:wait:/etc/rc.d/rc 0 rc0.d/ K* stop S* start /etc/rc.d/init.d, /etc/init.d 服务类脚本: start SysV: /etc/rc.d/init.d start|stop|restart|status reload|configtest chkconfig # chkconfig: runlevels SS KK 当chkconfig命令来为此脚本在rc#.d目录创建链接时,runlevels表示默认创建为S*开头的链接,-表示没有级别默认为S*开头的链接;除此之外的级别默认创建为K*开头的链接; S后面的启动优先级为SS所表示的数字;K后面关闭优先次序为KK所表示的数字; # description: 用于说明此脚本的简单功能; \, 续行 chkconfig --list: 查看所有独立守护服务的启动设定;独立守护进程! chkconfig --list SERVICE_NAME chkconfig --add SERVICE_NAME chkconfig --del SERVICE_NAME chkconfig [--level RUNLEVELS] SERVICE_NAME {on|off} 如果省略级别指定,默认为2345级别; 样例脚本: #!/bin/bash # # chkconfig: 2345 77 22 # description: Test Service # LOCKFILE=/var/lock/subsys/myservice status() { if [ -e $LOCKFILE ]; then echo "Running..." else echo "Stopped." fi } usage() { echo "`basename $0` {start|stop|restart|status}" } case $1 in start) echo "Starting..." touch $LOCKFILE ;; stop) echo "Stopping..." rm -f $LOCKFILE &> /dev/null ;; restart) echo "Restarting..." ;; status) status ;; *) usage ;; esac /etc/rc.d/rc.local:系统最后启动的一个服务,准确说,应该执行的一个脚本; /etc/inittab的任务: 1、设定默认运行级别; 2、运行系统初始化脚本; 3、运行指定运行级别对应的目录下的脚本; 4、设定Ctrl+Alt+Del组合键的操作; 5、定义UPS电源在电源故障/恢复时执行的操作; 6、启动虚拟终端(2345级别); 7、启动图形终端(5级别); 守护进程的类型: 独立守护进程 xinetd:超级守护进程,代理人 瞬时守护进程:不需要关联至运行级别 核心:/boot/vmlinuz-version 内核模块(ko): /lib/modules/version/ 内核设计: 单内核 模块化设计 微内核 装载模块: insmod modprobe www.kernel.org: 用户空间访问、监控内核的方式: /proc, /sys 伪文件系统 /proc/sys: 此目录中的文件很多是可读写的 /sys/: 某些文件可写 设定内核参数值的方法: echo VALUE > /proc/sys/TO/SOMEFILE sysctl -w kernel.hostname= 能立即生效,但无法永久有效; 永久有效:/etc/sysctl.conf 修改文件完成之后,执行如下命令可立即生效: sysctl -p sysctl -a: 显示所有内核参数及其值 内核模块管理: lsmod: 查看 modprobe MOD_NAME:装载某模块 modprobe -r MOD_NAME: 卸载某模块 modinfo MOD_NAME: 查看模块的具体信息 insmod /PATH/TO/MODULE_FILE: 装载模块 rmmod MOD_NAME depmod /PATH/TO/MODILES_DIR 内核中的功能除了核心功能之外,在编译时,大多功能都有三种选择: 1、不使用此功能; 2、编译成内核模块; 3、编译进内核; 如何手动编译内核: make gconfig: Gnome桌面环境使用,需要安装图形开发库组:GNOME Software Development make kconfig: KDE桌面环境使用,需要安装图形开发库 make menuconfig: make make modules_install make install screen命令: screen -ls: 显示已经建立的屏幕 screen: 直接打开一个新的屏幕 Ctrl+a, d: 拆除屏幕 screen -r ID: 还原回某屏幕 exit: 退出 二次编译时清理,清理前,如果有需要,请备份配置文件.config: make clean make mrproper grub-->kernel-->initrd-->ROOTFS(/sbin/init, /bin/bash) mkinitrd initrd文件路径 内核版本号 mkinitrd /boot/initrd-`uname -r`.img `uname -r` ${parameter#*word} ${parameter##*word} The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches the beginning of the value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ?.€.?.€ case) or the longest matching pattern (the ?.€.#?.€.case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable sub- scripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. FILE=/usr/local/src ${FILE#*/}: usr/local/src ${FILE##*/}: src ${FILE%/*}: /usr/local ${FILE%%/*}: ${parameter%word*} ${parameter%%word*} The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ?.€.?.€.case) or the longest matching pattern (the ?.€.%?.€.case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. 复制二进制程序及其依赖的库文件的脚本: #!/bin/bash # DEST=/mnt/sysroot libcp() { LIBPATH=${1%/*} [ ! -d $DEST$LIBPATH ] && mkdir -p $DEST$LIBPATH [ ! -e $DEST${1} ] && cp $1 $DEST$LIBPATH && echo "copy lib $1 finished." } bincp() { CMDPATH=${1%/*} [ ! -d $DEST$CMDPATH ] && mkdir -p $DEST$CMDPATH [ ! -e $DEST${1} ] && cp $1 $DEST$CMDPATH for LIB in `ldd $1 | grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`; do libcp $LIB done } read -p "Your command: " CMD until [ $CMD == 'q' ]; do ! which $CMD &> /dev/null && echo "Wrong command" && read -p "Input again:" CMD && continue COMMAND=` which $CMD | grep -v "^alias" | grep -o "[^[:space:]]\{1,\}"` bincp $COMMAND echo "copy $COMMAND finished." read -p "Continue: " CMD done /etc/rc.d/rc.sysdone脚本,可用于实现为微型的Linux系统关机 #!/bin/bash # sync sleep 2 sync mount | awk '{print $3}' | grep -v -E "\/(dev|proc|sys)?$" | sort -r | while read LINE; do umount -n -f $LINE [ $? -eq 0 ] && echo "Unmount $LINE finished." || echo "Can not unmount $LINE." done mount | awk '{print $3}' | while read LINE; do mount -n -o remount,ro $LINE [ $? -eq 0 ] && echo "Remount $LINE finished." || echo "Can not remount $LINE." done exec /sbin/halt -p T_RED="\\033[1;31m" # bold+red T_GREEN="\\033[1;32m" # bold+green T_YELLOW="\\033[1;33m" # bold+yellow T_BLUE="\\033[1;34m" # bold+blue T_CYAN="\\033[1;36m" # cyan T_BOLD="\\033[1;37m" # bold+white T_NORM="\\033[0;39m" # normal 系统启动流程: POST-->BIOS(Boot Sequence)--> BootLoader(MBR)--> Kernel(initrd,initramfs)--> init (/etc/inittab) /etc/inittab: 设定默认运行级别 系统初始化(/etc/rc.d/rc.sysinit) 运行指定级别的服务脚本 /etc/rc.d/init.d/ /etc/rc.d/rc#.d rc0.d--rc6.d K* S* 00-99:运行次序 启动虚拟终端 启动图形终端 /etc/rc.d/rc.sysinit: 检测并以读写方式重新挂载根文件系统; 设定主机名; 检测并挂载/etc/fstab中的其它文件系统; 启动swap分区; 初始化外围硬件设备的驱动; 根据/etc/sysctl.conf设定内核参数; 激活udev和selinux; 激活LVM和RAID设备; 清理过期锁和PID文件; 装载键映射; /etc/inittab id:3:initdefault: si::sysinit:/etc/rc.d/rc.sysinit /etc/rc.d/rc.sysinit echo insmod ifconfig /bin/bash 1、关机和重启; 2、主机名; 3、运行对应服务脚本; 4、启动终端; 5、运行用户; 6、定义单用户级别; 7、装载网卡驱动,启用网络功能; 8、提供一个web服务器; 9、设定内核参数; busybox: 1M Kernel: RHEL5, RHEL6 定制安装: 自动化安装 定制引导盘 mount -n: 挂载时不更新/etc/mtab文件; cat /proc/mounts 脚本编程知识点: 1、变量中字符的长度:${#VARNAME} 2、变量赋值等: ${parameter:-word}:如果parameter为空或未定义,则变量展开为“word”;否则,展开为parameter的值; ${parameter:+word}:如果parameter为空或未定义,不做任何操作;否则,则展开为“word”值; ${parameter:=word}:如果parameter为空或未定义,则变量展开为“word”,并将展开后的值赋值给parameter; ${parameter:offset} ${parameter:offset:length}:取子串,从offset处的后一个字符开始,取lenth长的子串; 3、脚本配置文件 /etc/rc.d/init.d/服务脚本 服务脚本支持配置文件:/etc/sysconfig/服务脚本同名的配置文件 4、局部变量 local VAR_NAME= a=1 test() { a=$[3+4] } test for I in `seq $a 10`; do echo $I done 5、命令mktemp 创建临时文件或目录 mktemp /tmp/file.XX -d: 创建为目录 6、信号 kill -SIGNAL PID 1: HUP 2: INT 9: KILL 15: TERM 脚本中,能实现信号捕捉,但9和15无法捕捉 Ctrl+c: SIGINT trap命令: trap 'COMMAND' 信号列表 7、一行执行多个语句,语句间用分号分隔 任务计划: 1、在未来的某个时间点执行一次某任务; at batch at 时间 at> COMMAND at> Ctrl+d 指定时间: 绝对时间:HH:MM, DD.MM.YY MM/DD/YY 相对时间:now+# 单位:minutes, hours, days, weeks 模糊时间:noon, midnight, teatime 命令的执行结果:将以邮件的形式发送给安排任务的用户 at -l = atq at -d AT_JOB_ID = atrm AT_JOB_ID 2、周期性地执行某任务; cron:自身是一个不间断运行的服务 anacron: cron的补充,能够实现让cron因为各种原因在过去的时间该执行而未执行的任务在恢复正常执行一次; cron: 系统cron任务: /etc/crontab 分钟 小时 天 月 周 用户 任务 用户cron任务: /var/spool/cron/USERNAME 分钟 小时 天 月 周 任务 时间的有效取值: 分钟:0-59 小时:0-23 天:1-31 月:1-12 周:0-7,0和7都表示周日 时间通配表示: *: 对应时间的所有有效取值 3 * * * * 3 * * * 7 13 12 6 7 * ,: 离散时间点: 10,40 02 * * 2,5 -:连续时间点: 10 02 * * 1-5 /#: 对应取值范围内每多久一次 */3 * * * * 每两小时执行一次: 08 */2 * * * 每两天执行一次: 10 04 */2 * * 执行结果将以邮件形式发送给管理员: */3 * * * * /bin/cat /etc/fstab &> /dev/null cron的环境变量:cron执行所有命令都去PATH环境变量指定的路径下去找 PATH /bin:/sbin:/usr/bin:/usr/sbin 用户任务的管理: crontab -l: 列出当前用户的所有cron任务 -e: 编辑 -r: 移除所有任务 -u USERNAME: 管理其用户的cron任务 anacron: cross compile:交叉编译 x86, 32bit, ARM shutdown halt reboot poweroff init 0 init 6 RHEL6: upstart --> init /etc/inittab /etc/init/*.conf /etc/rc.d/init.d/functions脚本,可用于控制服务脚本的信息显示: SCREEN=`stty -F /dev/console size 2>/dev/null` COLUMNS=${SCREEN#* } [ -z $COLUMNS ] && COLUMNS=80 SPA_COL=$[$COLUMNS-14] RED='\033[31m' GREEN='\033[32m' YELLOW='\033[33m' BLUE='\033\34m' NORMAL='\033[0m' success() { string=$1 RT_SPA=$[$SPA_COL-${#string}] echo -n "$string" for I in `seq 1 $RT_SPA`;do echo -n " " done echo -e "[ ${GREEN}OK${NORMAL} ]" } failure() { string=$1 RT_SPA=$[$SPA_COL-${#string}] echo -n "$string" for I in `seq 1 $RT_SPA`;do echo -n " " done echo -e "[ ${RED}FAILED${NORMAL} ]" } /etc/rc.d/init.d/tserver脚本,测试SysV服务的定义格式: #!/bin/bash # # chkconfig: 35 66 33 # description: test service script # . /etc/rc.d/init.d/functions prog=tserver lockfile=/var/lock/subsys/$prog start() { touch $lockfile [ $? -eq 0 ] && success "Starting $prog" || failure "Staring $prog" } stop() { rm -f $lockfile [ $? -eq 0 ] && success "Stopping $prog" || failure "Stopping $prog" } status() { if [ -f $lockfile ]; then echo "Running..." else echo "Stopped..." fi } usage() { echo "Usage: $prog {start|stop|status|restart}" } case $1 in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) usage exit 1 ;; esac /etc/inittab文件示例: id:3:initdefault: si::sysinit:/etc/rc.d/rc.sysinit l0:0:wait:/etc/rc.d/rc 0 l3:3:wait:/etc/rc.d/rc 3 l6:6:wait:/etc/rc.d/rc 6 1:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty1 2:2345:respawn:/sbin/agetty -n -l /bin/bash 38400 tty2 /etc/fstab文件示例: /dev/hda2 / ext3 defaults 0 0 /dev/hda1 /boot ext3 defaults 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 /etc/rc.d/rc.sysinit脚本示例: #!/bin/bash # echo -e "\tWelcome to \033[34mMageEdu\033[0m Linux" echo "Remount rootfs..." mount -n -o remount,rw / echo "Set the hostname..." [ -f /etc/sysconfig/network ] && . /etc/sysconfig/network [ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost /bin/hostname $HOSTNAME echo "Initializing network device..." /sbin/insmod /lib/modules/mii.ko /sbin/insmod /lib/modules/pcnet32.ko /etc/rc.d/rc脚本示例: #!/bin/bash # RUNLEVEL=$1 for I in /etc/rc.d/rc$RUNLEVEL.d/K*; do $I stop done for I in /etc/rc.d/rc$RUNLEVEL.d/S*; do $I start done 1、关机和重启; 2、终端 3、主机名 4、IP地址(模块的装载和服务的实现) 5、functions 6、终端提示信息 /etc/issue文件的内容 7、rc.sysinit:挂载/etc/fstab中定义的其它文件系统; 8、设定内核参数 /etc/sysctl.conf sysctl -p 9、用户 PAM: Pluggable Authentication Module /etc/pam.d/* 绕过PAM, /bin/login: 用户:UID 组: GID login: 验正 nsswitch: Network Service Switch 框架:/etc/passwd, /etc/shadow, /etc/group 库:libnss_file.so, libnss_nis.so, libnsss_ldap.so 配置文件: /etc/nsswitch.conf /etc/passwd, /etc/shadow NIS, LDAP, MySQL /etc/mypasswd /etc/passwd /etc/group 名称解析是如何工作的? 10、单用户模式 内核编译: busybox: Kernel+ROOTFS() kernel+initrd(ramdisk) kernel+ busybox-->initrd kernel+initrd(busybox)-->rootfs(busybox) kenrel RHEL5.8 + busybox(initrd) + rootfs(busybox) 查看本机硬件设备信息: 1、cat /proc/cpuinfo 2、lsusb 3、lspci 4、hal-device Hardware Abstract Layer 编译内核: 1、配置 make menuconfig make gconfig make kconfig make oldconfig make config 保存为.config 2、 make make modules_install make install 模块安装位置:/lib/modules/KERNEL_VERSION/ 如何实现部分编译: 1、只编译某子目录下的相关代码: make dir/ make arch/ make drivers/net/ 2、只编译部分模块 make M=drivers/net/ 3、只编译某一模块 make drivers/net/pcnet32.ko 4、将编译完成的结果放置于别的目录中 make O=/tmp/kernel 5、交叉编译 make ARCH= 如何编译busybox: IDE: /dev/hda1: ext3 /boot /dev/hda2: ext3 / 内核初始化: 硬件探测 装载驱动 挂载根文件系统(rootfs) 启动用户空间中的第一个进程init http://youbest.cublog.cn 文件系统 进程管理 内存管理 网络管理 安全功能 驱动程序 Linux内核及编译 Linux系统安装和kickstart 故障排除 Kernel + initrd(busybox制作,提供ext3文件系统模块) + ROOTFS (busybox制作) make arch/ arch/x86/boot/bzImage 硬件驱动:initrd initrd: 仅需要提供内核访问真正的根文件系统所在设备需要的驱动 存储设备和文件系统相关的模块 系统初始化rc.sysinit: 初始其它硬件的驱动程序; ROOTFS: busybox, init不支持运行级别 /etc/inittab: 格式也不尽相同 ash, hush bash 内核编译: make SUBDIR=arch/ make arch/x86/ /boot/vmlinuz (ext3, IDE) /mnt/boot: /dev/hda1 /mnt/sysroot: /dev/hda2 1、安装grub 2、提供内核 3、提供initrd 4、创建根文件系统 Linux上的日志系统 syslog syslog-ng: 开源 日志系统:syslog() A: B: D: syslog服务: syslogd: 系统,非内核产生的信息 klogd:内核,专门负责记录内核产生的日志信息 kernel --> 物理终端(/dev/console) --> /var/log/dmesg # dmesg # cat /var/log/dmesg 日志需要滚动(日志切割): messages messages.1 messages.2 messages.3 /sbin/init /var/log/messages: 系统标准错误日志信息;非内核产生引导信息;各子系统产生的信息; /var/log/maillog: 邮件系统产生的日志信息; /var/log/secure: syslog: syslogd klogd 配置文件:/etc/syslog.conf 信息详细程序:日志级别 子系统:facility, 设施 动作: syslog: syslogd和klogd 配置文件定义格式为: facility.priority action facility,可以理解为日志的来源或设备目前常用的facility有以下几种: auth # 认证相关的 authpriv # 权限,授权相关的 cron # 任务计划相关的 daemon # 守护进程相关的 kern # 内核相关的 lpr # 打印相关的 mail # 邮件相关的 mark # 标记相关的 news # 新闻相关的 security # 安全相关的,与auth 类似 syslog # syslog自己的 user # 用户相关的 uucp # unix to unix cp 相关的 local0 到 local7 # 用户自定义使用 * # *表示所有的facility priority(log level)日志的级别,一般有以下几种级别(从低到高) debug # 程序或系统的调试信息 info # 一般信息 notice # 不影响正常功能,需要注意的消息 warning/warn # 可能影响系统功能,需要提醒用户的重要事件 err/error # 错误信息 crit # 比较严重的 alert # 必须马上处理的 emerg/panic # 会导致系统不可用的 * # 表示所有的日志级别 none # 跟* 相反,表示啥也没有 action(动作)日志记录的位置 系统上的绝对路径 # 普通文件 如: /var/log/xxx | # 管道 通过管道送给其他的命令处理 终端 # 终端 如:/dev/console @HOST # 远程主机 如: @10.0.0.1 用户 # 系统用户 如: root * # 登录到系统上的所有用户,一般emerg级别的日志是这样定义的 定义格式例子: mail.info /var/log/mail.log # 表示将mail相关的,级别为info及 # info以上级别的信息记录到/var/log/mail.log文件中 auth.=info @10.0.0.1 # 表示将auth相关的,基本为info的信息记录到10.0.0.1主机上去 # 前提是10.0.0.1要能接收其他主机发来的日志信息 user.!=error # 表示记录user相关的,不包括error级别的信息 user.!error # 与user.error相反 *.info # 表示记录所有的日志信息的info级别 mail.* # 表示记录mail相关的所有级别的信息 *.* # 你懂的. cron.info;mail.info # 多个日志来源可以用";" 隔开 cron,mail.info # 与cron.info;mail.info 是一个意思 mail.*;mail.!=info # 表示记录mail相关的所有级别的信息,但是不包括info级别的 telnet: 远程登录协议, 23/tcp C/S S:telnet服务器 C:telnet客户端 ssh: Secure SHell, 应用层协议,22/tcp 通信过程及认证过程是加密的,主机认证 用户认证过程加密 数据传输过程加密 ssh v1, v2 man-in-middle sshv2 认证过程: 基于口令认证 基于密钥认证: 协议:规范 实现:服务器端、客户端 Linux: openSSH C/S 服务器端:sshd, 配置文件/etc/ssh/sshd_config 客户端:ssh, 配置文件/etc/ssh/ssh_config ssh-keygen: 密钥生成器 ssh-copy-id: 将公钥传输至远程服务器 scp:跨主机安全复制工具 ssh: ssh USERNAME@HOST ssh -l USERNAME HOST ssh USERNAME@HOST 'COMMAND' scp: scp SRC DEST -r -a scp USERNAME@HOST:/path/to/somefile /path/to/local scp /path/to/local USERNAME@HOST:/path/to/somewhere ssh-keygen -t rsa ~/.ssh/id_rsa ~/.ssh/id_rsa.pub -f /path/to/KEY_FILE -P '': 指定加密私钥的密码 公钥追加保存到远程主机某用户的家目录下的.ssh/authorized_keys文件或.ssh/authorized_keys2文件中 ssh-copy-id -i ~/.ssh/id_rsa.pub ssh-copy-id -i ~/.ssh/id_rsa.pub USERNAME@HOST dropbear: 嵌入式系统专用的ssh服务器端和客户端工具 服务器端:dropbear dropbearkey 客户端:dbclient dropbear默认使用nsswitch实现名称解析 /etc/nsswitch.conf /lib/libnss_files* /usr/lib/libnss3.so /usr/lib/libnss_files* dropbear会在用户登录检查其默认shell是否当前系统的安全shell /etc/shells 主机密钥默认位置: /etc/dropbear/ RSA: dropbear_rsa_host_key 长度可变, 只要是8的整数倍,默认为1024 DSS: dropbear_dss_host_key 长度固定,默认为1024 dropbearkey -t rsa|dsa -f /path/to/KEY_FILE -s SIZE 博客作业: 日志系统 cron任务计划 shell知识点总结及例子 RHEL5.8系统裁减:具有用户登录等功能 微型系统制作:具有IP地址、有虚拟终端、有主机名、能ssh远程登录;