btrfs特性,压缩归档,for循环,程序包管理(第9天)

1:btrfs文件系统:
技术预览版
Btrfs (B-tree, Butter FS, Better FS), GPL, Oracle, 2007, CoW(写时复制);
ext3/ext4, xfs

btrfs核心特性:
多物理卷支持:btrfs可由多个底层物理卷组成;支持RAID,以联机“添加”、“移除”,“修改”;
写时复制更新机制(CoW):复制、更新及替换指针,而非“就地”更新;
数据及元数据校验码:checksum
子卷:sub_volume
快照:支持快照的快照;
透明压缩

文件系统创建:
mkfs.btrfs命令的使用
-L 'LABEL'
-d <type>指明数据如何存放,type有raid0, raid1, raid5, raid6, raid10, single
-m <profile> 指明元数据如何存放,profile有raid0, raid1, raid5, raid6, raid10, single, dup
-O <feature> 开启特性。可以使用 -O list-all: 列出支持的所有feature;
例子 mkfs.btrfs -L "my_btrfs" /dev/sdb  /dev/sdc  其中sdb和sdb可以不分区,而直接安装btrfs文件系统

属性查看:
btrfs filesystem show   filesystem是btrfs的子命令,show是filesystem的子命令

挂载文件系统:
mount -t btrfs /dev/sdb MOUNT_POINT   挂载使用

透明压缩机制:
mount -o compress={lzo|zlib} DEVICE MOUNT_POINT

btrfs的子命令:filesystem, device(添加,删除底层设备), balance(平衡数据), subvolume(子卷)

博客作业:btrfs管理及应用

2:压缩和解压缩

压缩和归档工具如下:
compress/uncompress: .Z
gzip/gunzip: .gz
bzip2/bunzip2: .bz2
xz/unxz: .xz
zip/unzip
tar, cpio

1、gzip/gunzip   压缩和解压缩后会删除原文件
gzip [OPTION]... FILE ...
      -d: 解压缩,相当于gunzip
      -c: 将结果输出至标准输出;
      -#:1-9,指定压缩比;
      -r  对目录中的文件递归压缩

例子  gzip  message  将message压缩成message.gz
         gunzip  -c message.gz  将message.gz解压缩后的结果输出到标准输出

zcat:不显式展开的前提下查看文本文件内容;
例如  zcat  message.gz

2、bzip2/bunzip2/bzcat
bzip2 [OPTION]... FILE ...
      -k: keep, 保留原文件;
      -d:解压缩,相当于bunzip2
      -#:1-9,压缩比,默认为6;
例子 bzip2  -k message 将message文件压缩为message.bz2

bzcat:不显式展开的前提下查看文本文件内容;

3、xz/unxz/xzcat
xz [OPTION]... FILE ...
      -k: keep, 保留原文件;
      -d:解压缩
      -#:1-9,压缩比,默认为6;

xzcat: 不显式展开的前提下查看文本文件内容;

4、tar
tar [OPTION]...   不会删除原文件
(1) 创建归档(-zcvf) -c选项表示creat归档
      tar -c -f /PATH/TO/SOMEFILE.tar FILE...
      tar  -cf  /PATH/TO/SOMEFILE.tar FILE...

(2) 查看归档文件中的文件列表
      tar -t -f /PATH/TO/SOMEFILE.tar

(3) 展开归档(-zxvf) -x选项表示展开归档
      tar -x -f /PATH/TO/SOMEFILE.tar
      tar -x -f /PATH/TO/SOMEFILE.tar -C /PATH/TO/DIR

      结合压缩工具实现:归档并压缩
      -j: 调用bzip2压缩和解压缩, -z: 调用gzip, -J: 调用xz

3:bash脚本编程
if语句
bash -n选项  -x选项

CONDITION :if条件里可以放bash命令,就是if后面可以跟bash命令,但是是使用命令的执行状态结果来判断的。如果命令执行成功表示条件为true,如果命令执行失败表示条件为false。

成功或失败的意义:取决于用到的命令;

单分支:
if CONDITION; then
      if-true
fi

双分支:
if CONDITION; then
      if-true
else
      if-false
fi

多分支: 逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束;
if CONDITION1; then
      if-true
elif CONDITION2; then
      if-ture
elif CONDITION3; then
      if-ture
...
esle
      all-false
fi

示例:用户键入文件路径,脚本来判断文件类型;
#!/bin/bash
#
read -p "Enter a file path: " filename

if [ -z "$filename" ]; then
   echo "Usage: Enter a file path."
   exit 2
fi

if [ ! -e $filename ]; then
   echo "No such file."
   exit 3
fi

if [ -f $filename ]; then
   echo "A common file."
elif [ -d $filename ]; then
   echo "A directory."
elif [ -L $filename ]; then
   echo "A symbolic file."
else
   echo "Other type."
fi

注意:if语句可嵌套;

循环:for, while, until:
循环体:要执行的代码;可能要执行n遍;
进入条件:
退出条件:

for循环格式如下:
for 变量名  in 列表; do
      循环体
done

执行机制:依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束;

示例:添加10个用户, user1-user10;密码同用户名;
#!/bin/bash
if [ ! $UID -eq 0 ]; then
      echo "Only root."
      exit 1
fi

for i in {1..10}; do
  if id user$i &> /dev/null; then
  echo "user$i exists."
      else
            useradd user$i
            if [ $? -eq 0 ]; then
             echo "user$i" | passwd --stdin user$i &> /dev/null
              echo "Add user$i finished."
       fi
   fi
done

for循环的列表生成方式有如下的方法:
(1) 直接给出列表;
(2) 整数列表有2种:(a) {start..end}  (b) $(seq [start [step]] end)
(3) 返回列表的命令,比如$(COMMAND)
(4) glob  通配符
(b) 变量引用,比如 $@, $*

示例:判断某路径下所有文件的类型
#!/bin/bash
#
for file in $(ls /var); do
      if [ -f /var/$file ]; then
echo "Common file."
  elif [ -L /var/$file ]; then
echo "Symbolic file."
  elif [ -d /var/$file ]; then
echo "Directory."
  else
echo "Other type."
  fi
done

示例:查看netstat -tan的结果里ESTABLISHED,LISTEN状态各有有多少个?
#!/bin/bash
#
declare -i estab=0
declare -i listen=0
declare -i other=0

for state in $(  netstat -tan | grep "^tcp\>" | awk '{print $NF}'  ); do
    if [ "$state" == "ESTABLISHED" ]; then
        let estab++
    elif [ "$state" == 'LISTEN' ]; then
        let listen++
    else
        let other++
    fi
done

echo "ESTABLISHED: $estab"
echo "LISTEN: $listen"
echo "Unkown: $other"

练习1:/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;
分别读取每个文件,以K开头的文件输出为文件加stop,以S开头的文件输出为文件名加start;
“K34filename stop”
“S66filename start”
#!/bin/bash
for file in `ls /etc/rc.d/rc3.d`; do
    if echo $file | grep "^K" /dev/null ; then
        echo "$file stop"
    elif echo $file | grep "^S" /dev/null ; then
        echo "$file start"
    fi
done

练习2:写一个脚本,使用ping命令探测192.168.62.1-254之间的主机的在线状态;
#!/bin/bash
for i in {1..254};do
    if ping -w 1 192.168.62.$i &> /dev/null ; then
        echo "192.168.62.$i online"
    else
        echo "192.168.62.$i offline"
    fi
done

4:linux程序包管理
API:Application Programming Interface  应用编程接口
POSIX:Portable OS, 各个平台的API符合POSIX规范,函数名和参数都一样。这样一来,源代码就可以在各个平台上兼容。

程序源代码 --> 预处理(宏展开等) --> 编译(编译成目标文件) --> 汇编 --> 链接
静态编译:编译的时候,将需要的lib直接编译进去二进制文件中,不用依赖外部环境
共享编译:.so

ABI:Application Binary Interface
Windows的ABI与Linux的ABI不兼容
库级别的虚拟化:Linux平台使用 WINE;Windows平台使用 Cywin

系统级开发:C/C++
应用级开发
      java
      Python
      php
      perl
      ruby

二进制应用程序的组成部分:二进制文件、库文件(自己的应用需要用到的库和供别的应用调用的库)、配置文件、帮助文件

程序包管理器:
debian:格式.deb, 包管理器是dpt
redhat: 使用rpm, rpm   rpm: Redhat Package Manager
       RPM is Package Manager
Gentoo
Archlinux

源代码:name-VERSION.tar.gz
VERSION可以表示为major.minor.release

rpm包命名方式:
name-VERSION-release.arch.rpm
VERSION可以表示为major.minor.release
release可以表示为release.OS
常见的arch:
      x86: i386, i486, i586, i686
      x86_64: x64, x86_64, amd64
      powerpc: ppc
      跟平台无关:noarch
例如  zlib-1.2.7-13.el7.i686.rpm  其中zlib表示包的名称,1.2.7表示版本号,13.el7表示操作系统,i686表示cpu平台。

testapp: 拆包
testapp-VERSION-ARCH.rpm: 主包
testapp-devel-VERSION-ARCH.rpm:支包
testapp-testing-VERSION-ARHC.rpm  测试包

包之间:存在依赖关系
X, Y, Z
yum:rpm包管理器的前端工具,自动分析包之间的依赖关系;
apt-get:deb包管理器前端工具,自动分析包之间的依赖关系;
zypper: suse上的rpm前端管理工具,自动分析包之间的依赖关系;
dnf: Fedora 22+ rpm包管理器前端管理工具,自动分析包之间的依赖关系;

查看二进制程序所依赖的库文件:
ldd /PATH/TO/BINARY_FILE
例如  ldd /bin/ls  查看ls依赖哪些共享库。

管理及查看本机装载的库文件:ldconfig
/sbin/ldconfig -p  显示本机已经缓存的所有可用库文件名及文件路径映射关系;
配置文件为:/etc/ld.so.conf, /etc/ld.so.conf.d/*.conf
缓存文件:/etc/ld.so.cache


程序包管理:
功能:将编译好的应用程序的各组成文件打包成一个或几个程序包文件,从而方便快捷地实现程序包的安装、卸载、查询、升级和校验等管理操作;
1、程序的组成组成清单 (每个包独有)
      文件清单
      安装或卸载时运行的脚本
2、数据库(公共)
      程序包名称及版本
      依赖关系;
      功能说明;
      安装生成的各文件的文件路径及校验码信息;


管理程序包的方式:
使用包管理器:rpm
使用前端工具:yum, dnf

获取程序包的途径:
(1) 系统发版的光盘或官方的服务器;
CentOS镜像:
      http://mirrors.aliyun.com
      http://mirrors.sohu.com
      http://mirrors.163.com

(2) 项目官方站点
(3) 第三方组织:
Fedora-EPEL
搜索引擎:
      http://pkgs.org
      http://rpmfind.net
      http://rpm.pbone.net
(4) 自己制作

建议检查程序包的其法性,包括如下:
来源合法性;
程序包的完整性;

CentOS系统上rpm命令管理程序包:安装、卸载、升级、查询、校验、数据库维护

安装:
rpm {-i|--install} [install-options] PACKAGE_FILE ...
      -v   表示verbose,显示详细信息
      -vv 显示调试的详细信息
      -h   以#号显示程序包管理执行进度;每个#表示2%的进度
例子  rpm -ivh PACKAGE_FILE ...  安装软件包

install-options:安装的时候可以使用的选项,在卸载,升级等也可以使用
--test: 测试安装,但不真正执行安装过程;dry run模式;
--nodeps:忽略依赖关系;
--replacepkgs: 重新安装;

--nosignature: 不检查来源合法性,不签名;
--nodigest:不检查包完整性;
例如 rpm -ivh PACKAGE_FILE --nosignature --nodigest

--noscipts:不执行程序包脚本片断,每个rpm包可能有4个脚本;
      %pre: 安装前脚本; --noscripts %pre相当于--nopre
      %post: 安装后脚本; --noscripts %post相当于--nopost
      %preun: 卸载前脚本; --noscripts %preun相当于--nopreun
      %postun: 卸载后脚本;  --noscripts %postun相当于--nopostun
例如  rpm -ivh PACKAGE_FILE --nopre   不执行安装前脚本

升级:有如下2种方式
rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...
rpm {-F|--freshen} [install-options] PACKAGE_FILE ...
upgrage:安装有旧版程序包,则“升级”;如果不存在旧版程序包,则“安装”;
freeshen:安装有旧版程序包,则“升级”;如果不存在旧版程序包,则不执行升级操作;
例如  rpm -Uvh PACKAGE_FILE ...
         rpm -Fvh PACKAGE_FILE ...

升级时候的选项也可以使用如上的install-options
--oldpackage:降级;
--force: 强行升级;

注意:(1) 不要对内核做升级操作;Linux支持多内核版本并存,因此,对直接安装新版本内核;
(2) 如果原程序包的配置文件安装后曾被修改,升级时,新版本的提供的同一个配置文件并不会直接覆盖老版本的配置文件,而把新版本的文件重命名(FILENAME.rpmnew)后保留;


查询:
rpm {-q|--query} [select-options] [query-options]

select-options:选择选项
-a  所有已安装的包   例如 rpm -qa  | grep php 查询所有已安装的包中包名有php关键字的
-f  查看指定的文件由哪个程序包安装生成   例如 rpm -qf /etc/fstab
-p /PATH/TO/PACKAGE_FILE:针对尚未安装的程序包文件做查询操作;
      例如 rpm -ql -p wireshark-gnome-1.10.14-10.el7.x86_64.rpm
--whatprovides CAPABILITY:查询指定的CAPABILITY(文件)由哪个包所提供;
      例如  rpm -q --whatprovides /sbin/ip  查询/sbin/ip这个文件由哪个包提供
--whatrequires CAPABILITY:查询指定的CAPABILITY被哪个包所依赖;

query-options:查询选项
--changelog:查询rpm包的changlog  例如 rpm -q --changelog zsh
-c: 查询程序的配置文件  rpm -qc zsh
-d: 查询程序的文档      rpm -qd zsh
-i: information 显示包的版本信息,名称等等  rpm -qi zsh
-l: 查看指定的程序包安装后生成的所有文件     rpm -ql zsh
--scripts:查询程序包自带的脚本片断    rpm -q --scripts zsh
-R: 查询指定的程序包所依赖的CAPABILITY  rpm -q -R  zsh
--provides: 列出指定程序包所提供的CAPABILITY   rpm -q --provides zsh

用法:
-qi PACKAGE, -qf FILE, -qc PACKAGE, -ql PACKAGE, -qd PACKAGE
-qpi PACKAGE_FILE, -qpl PACKAGE_FILE, ...
-qa

卸载:
rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts]
           [--notriggers] [--test] PACKAGE_NAME ...
例如 rpm -e  zsh

校验:
rpm {-V|--verify} [select-options] [verify-options]
校验包是否被修改过,可以修改的选项的有:
      S file Size differs
      M Mode differs (includes permissions and file type)
      5 digest (formerly MD5 sum) differs
      D Device major/minor number mismatch
      L readLink(2) path mismatch
      U User ownership differs
      G Group ownership differs
      T mTime differs
      P caPabilities differ
例如  rpm -V  zsh

数据库重建:rpm数据库  /var/lib/rmp
rpm {--initdb|--rebuilddb}
initdb: 初始化,如果事先不存在数据库,则新建之;否则,不执行任何操作;
rebuilddb:重建,无论当前存在与否,直接重新创建数据库;

包来源合法性验正及完整性验正:
完整性验正算法:SHA256
来源合法性验正算法,也就是包签名:RSA

note:这2步在包安装之前就必须做

对称加密:加密、解密使用同一密钥;
非对称加密:密钥是成对的,私钥加密,公钥解密
public key: 公钥,公开所有人
secret key: 私钥, 不能公开

整个过程如下:包的制作者制作好程序包之后,使用单向加密算法比如md5,sha算法对程序包提取摘要,并将该摘要附加到包上,之后,对整个包和摘要使用私钥加密。用户下载该包之后,使用包制作者发布的公钥解密出来程序包和摘要,然后是使用和制作者相同的单向加密算法提取包的摘要,将该计算出来的摘要和包里提供的摘要对比,看是否相同。

导入所需要的公钥:
rpm --import /PATH/FROM/GPG-PUBKEY-FILE
CentOS 7发行版光盘提供的密钥文件的文件名为:RPM-GPG-KEY-CentOS-7


评论

此博客中的热门博文

OAuth 2教程

网格策略

apt-get详细使用