# 文件处理

# 查看文件

# ls

$ ls [path]     # 列出指定目录(默认为当前目录)下的各个文件名(不包括隐藏文件)
      -a        # 显示所有文件(包括隐藏文件)
      -A        # 与 -a 相比,不显示相对目录 . 和 ..
      -l        # 显示文件的详细信息
      -h        # 以人类容易阅读的单位显示文件大小
      -d        # 只显示目录本身,不显示目录下的内容
      -i        # 显示文件指向的 inode 号
      -Z        # 增加显示一列安全上下文,格式为 user:role:type:level
  • 例:
    [[email protected] ~]# ls -al
    total 64
    dr-xr-x---.  7 root root   4096 Nov 27 19:17 .
    dr-xr-xr-x. 18 root root   4096 Oct 10 02:49 ..
    -rw-------   1 root root   6318 Dec  1 15:44 .bash_history
    -rw-r--r--.  1 root root     18 Dec 29  2013 .bash_logout
    -rw-r--r--.  1 root root    176 Dec 29  2013 .bash_profile
    -rw-r--r--.  1 root root    176 Dec 29  2013 .bashrc
    
    • total 表示已显示的这些文件占用的磁盘 block 总数。
    • 第一列,比如 dr-xr-x---. ,开头的 d 表示文件类型为目录,其后的 r-xr-x--- 表示文件的访问权限,末尾的 . 表示该文件使用了 SELinux 。(如果使用了 ACL 就会变成 + )
    • 第二列的数字表示指向该文件的 inode 的硬链接数。
    • 第三列、第四列表示文件所有者、所有者所属用户组。
    • 第五列表示文件的大小(单位为 Byte)。如果该文件是目录,则不包括目录中各文件的大小。
    • Nov 27 19:17 表示文件的最后修改时间。
    • 最后一列表示文件名。
  • 查询文件路径时,可使用以下匹配符号:
    [[email protected] ~]# touch f1 f2 f3
    [[email protected] ~]# ls f*          # 通配符 * 匹配任意个字符(包括零个)
    f1  f2  f3
    [[email protected] ~]# ls ?1          # 通配符 ? 匹配单个字符
    f1
    [[email protected] ~]# ls [a-z][0-2]  # 模式匹配在字符集中的单个字符。 [a-z] 不区分大小写,而 [abc] 区分大小写
    f1  f2
    

# du

$ du [path]... # 显示指定目录(默认为当前目录)及其子目录下的各个文件占用的磁盘空间
      -a       # 增加显示非目录文件
      -h       # 以人类容易阅读的单位显示文件大小
      -d n     # 最多显示 n 层子目录
      -s       # 只显示该目录占用的总磁盘空间
  • 例:
    du -ahd 1   # 显示当前目录下各个文件的大小,像 Windows 风格
    

# tree

$ tree [path]...   # 按树形结构显示某个目录(默认为当前目录)下的所有文件
       -a          # 增加显示隐藏文件
       -C          # 采用不同颜色显示不同类型的文件
       -L <n>      # 最多显示到第 n 层子目录
       -D          # 显示每个文件的最后修改时间
       -p          # 显示每个文件的访问权限
       -u          # 显示每个文件的所有者
       -sh         # 以人类容易阅读的单位显示文件大小
  • 安装: yum install tree

# lsof

$ lsof             # 显示目前所有被进程打开的文件
      <filename>   # 显示打开指定文件的所有进程
      -p <pid>     # 显示指定进程打开的所有文件
      -u <uid>     # 显示指定用户打开的所有文件

      -i           # 只显示 socket 文件
      -i :22       # 只显示指定端口的 socket 文件
  • 安装:yum install lsof

# 文件路径

# basename

$ basename <path>     # 获得一个路径的最后一段的名字
           [suffix]   # 去掉后缀
  • 不会检查输入的路径是否实际存在。
  • 例:
    [[email protected] ~]# basename /root/test.py .py
    test
    

# dirname

$ dirname <path>...   # 获得路径所属的目录
  • 如果输入的路径不包含 / ,则视作位于当前目录。
  • 例:
    [[email protected] ~]# dirname f1 /tmp
    .
    /
    

# realpath

$ realpath <path>...    # 将路径转换成绝对路径

# 查找文件

# find

$ find [path]               # 显示指定目录(默认是当前目录)下的所有文件(包括子目录)
        -exec echo {} \;    # 对每个找到的文件名(用 {} 表示)执行一条命令,该命令以 \; 结尾

        # 可以添加以下选项作为筛选条件
        -maxdepth 1         # 限制搜索的目录深度(默认为无限深)
        -type f             # 限制文件类型,类型可以是 f、d、l、s、c 等

        -name *.py          # 筛选文件名,采用 shell 风格的匹配
        -iname *.py         # 匹配时不区分大小写(insensitive)
        -path */test/*      # 筛选文件路径
        -ipath */test/*
        -regex .*py         # 筛选文件路径,采用正则匹配
        -iregex .*py

        -user root          # 属于指定用户的文件,可以使用 uid
        -group root         # 属于指定用户组的文件,可以使用 gid
        -perm <mode>        # 文件权限等于 mode ,mode 取值可以为 0644、644、u=rw-,g=rw,o=r 等格式,按二进制位进行匹配
        -perm -<mode>       # 文件权限大于 mode

        -size -10k          # 小于 10k 的文件
        -amin -3            # 过去 3 分钟之内被 access 的文件(同理还有 cmin、mmin )
        -atime -3           # 过去 3 天之内被 access 的文件(同理还有 ctime、mtime )
  • 筛选条件为数值类型时,有三种表示方式:
    n     # 等于
    +n    # 大于
    -n    # 小于
    
  • -size 选项可以使用以下单位:
    b     # blocks ,默认采用这种
    c     # bytes
    k     # kilo bytes
    M     # Mega bytes
    G     # Giga bytes
    
  • 例:
    [[email protected] ~]# touch 1.py
    [[email protected] ~]# ls -al
    total 8
    drwxrwxr-x.  2 root root   28 Jan  8 11:10 .
    drwx------. 14 root root 4096 Jan  8 10:52 ..
    -rw-rw-r--.  1 root root    0 Jan  8 11:10 1.py
    [[email protected] ~]# find . -name *.py
    ./1.py
    [[email protected] ~]# find . ! -name *.py            # 在筛选条件之前加冒号 ! 则表示反选
    .
    [[email protected] ~]# find . ! -name *.py ! -name .  # 可以重复使用同一种筛选条件
    
  • 例:查找并删除文件
    find . -name *.log -exec rm -f {} \;
    find . -name *.log | xargs -n 1 rm -f
    

# locate

$ locate [pattern]  # 显示文件路径包含 pattern 的所有文件
         -i         # pattern 不区分大小写
         -r         # pattern 采用正则表达式
  • 安装: yum install mlocate
  • locate 命令会从数据库 /var/lib/mlocate/mlocate.db 中查找文件,速度较快。该数据库一般每天更新一次,执行命令 updatedb 可立即更新。

# 移动文件

# rename

$ rename <源字符串> <目标字符串> <文件>...   # 替换文件名中的字符串
         -v                                # 显示每个被处理的文件
  • rename 命令主要用于批量重命名文件,不能像 mv 命令一样移动文件。

# mv

$ mv <src_path>... <dst_path> # 移动文件或目录
     -f     # 如果目标文件已存在,则覆盖它
     -i     # 如果目标文件已存在,则提示用户是否进行覆盖
     -u     # 当目标文件不存在,或源文件比目标文件新时,才执行移动(即 update)
  • mv 命令可以用于移动文件,也可以用于重命名文件(此时源路径只能有一个)。
    • 如果 dst_path 已存在且是一个文件,则考虑是否覆盖目标文件。
    • 如果 dst_path 已存在且是一个目录,则会将 src_path 移动到该目录之下。
    • 如果是在同一文件系统内 mv 文件,则只会重命名文件路径,依然使用源文件的 inode 号 。
    • 如果是跨文件系统 mv 文件,则会先拷贝源文件到目标路径(使用新的 inode 号),再删除源文件,相当于 cp f1 f2 && rm f1
      • 如果 mv 文件、文件夹的过程失败,并不会删除源文件。
  • 假设在同一文件系统内操作:
    • mv f1 f2
      • 如果 f2 不存在,则会将 f1 重命名为 f2 ,依然使用 f1 的 inode 号。
      • 如果 f2 已存在,则会先删除 f2 ,再将 f1 重命名为 f2 ,依然使用 f1 的 inode 号。
    • mv dir1/ dir2/
      • 如果 dir2 不存在,则将 dir1 重命名为 dir2 。
      • 如果 dir2 已存在,则将 dir1 移动到 dir2 之下,保存为 dir2/dir1 。
      • 如果 dir2/dir1 已存在且不为空,则会报错 cannot move 'dir1' to '/dir2/dir1': Directory not empty ,此时可以改用 cp -rf dir1 dir2 && rm -rf dir1
    • mv dir1/* dir2/
      • 将 dir1/ 目录下的所有文件移动到 dir2/ 目录下。
      • 当移动多个源文件时,目标路径只能是一个目录,因此末尾不加斜杆 / 也能自动识别。

# rm

$ rm <path>...  # 删除文件
     -d         # 删除目录(只能是空目录)
     -r         # 递归删除(用于删除非空目录)
     -i         # 若文件存在,则提示用户是否确认删除
     -f         # 强制删除(覆盖 -i 选项,且忽略文件不存在时的报错)
     -v         # 打印正在删除的文件列表
  • 例:
    rm -rfv *     # 强制删除当前目录下的所有文件
    

# 拷贝文件

  • 在本机上拷贝文件时:
    • 通常使用 cp 命令。
    • 跨磁盘拷贝文件时,两个磁盘分别承受读、写负载。在同一磁盘拷贝文件时,读、写负载同时作用于该磁盘,拷贝速度慢很多,不如创建硬链接。
  • 跨主机拷贝文件时:
    • 通常使用 scp、rsync 命令。
    • 跨主机拷贝文件时,磁盘 IO 速度可能比网络 IO 速度快多倍,比如 100MB/s 对 10MB/s 。建议先制作文件的压缩包,拷贝到目标主机之后再解压,使得总耗时更少,只是压缩、解压需要占用一些时间和 CPU 。
    • 拷贝大量小文件时,也建议制作压缩包。因为每个文件都需要拷贝一次文件元数据,增加了耗时。

# cp

$ cp <src_path> <dst_path>  # 将文件从源路径拷贝到目标路径
     -a       # 相当于-dpr
     -d       # 若源文件为 link file ,则复制 link file 的属性(而非文件本身)
     -p       # 将源文件的权限、属性也拷贝过去(否则会使用默认属性)
     -r       # 递归操作(用于复制目录)

     -f       # 若目标文件已存在,则删除它再尝试拷贝
     -i       # 若目标文件已存在,则提示用户是否进行覆盖
     -n       # 若目标文件已存在,则不覆盖
     -u       # --update ,当目标文件不存在,或源文件比目标文件更新时,才执行拷贝
     -v       # 显示执行过程的详细信息
  • Linux 发行版一般设置了 alias cp='cp -i' ,所以 -f 选项无效。
  • 例:
    cp f1 f2
    cp f1 f2 /tmp
    cp -r *  /tmp   # 源路径中包含通配符 * 时,不会拷贝隐藏文件
    cp -r .  /tmp
    cp -a *  /tmp
    
  • 执行 cp f1 f2 时:
    • 如果 f2 不存在,则会先创建一个空的 f2 文件,再将 f1 的内容拷贝过去。
    • 如果 f2 已存在,则会先将 f2 的内容清空,再将 f1 的内容拷贝过去,因此目标文件依然使用 f2 的 inode 号。
      • 如果该过程中有其它进程也在修改 f2 ,则会导致 cp 出错。

# ln

:用于创建文件的链接,并不会实际拷贝文件。

  • 命令:
    $ ln <src_path> <dst_path>  # 创建文件的硬链接
        -s    # 创建文件的软链接
        -f    # 若目标文件已存在,则覆盖它
    
    • 创建链接时,源路径、目标路径都必须是绝对路径。
    • 不支持给目录创建硬链接,不支持跨磁盘分区创建硬链接。
    • 可以给目录创建软链接,可以跨磁盘分区创建软链接。
  • 例:
    [[email protected] ~]# ln -s /tmp tmp
    [[email protected] ~]# ls -lh
    total 0
    lrwxrwxrwx 1 root root 4 Jan  8 14:21 tmp -> /tmp
    [[email protected] ~]# rm -f tmp/       # 如果软链接文件指向一个目录,删除时不能加上 / 后缀,否则会被视作删除目标目录
    rm: cannot remove ‘tmp/’: Is a directory
    [[email protected] ~]# rm -f tmp
    

# dd

:用于在本机上拷贝文件,还支持转换文件格式。不支持拷贝目录。

  • 命令:
    $ dd
          if=<file>          # 源文件,默认为 stdin
          of=<file>          # 目标文件,默认为 stdout
    
          count=<blocks>     # 拷贝多少个块(默认为拷贝全部数据)
          bs=<bytes>         # 读写数据时,内存缓冲区的大小。默认为 512 。取值过小会减慢速度,取值过大会占用大量内存
          ibs=<bytes>        # 每次读取多少字节的数据,默认为 512
          obs=<bytes>        # 每次写入多少字节的数据,默认为 512
    
    • dd 拷贝文件时,会以 ibs 为单位读取数据,放入内存缓冲区 bs ,然后以 obs 为单位写入目标文件。
  • 例:
    dd if=/dev/sda1 of=/dev/sda2    # 从 if 设备拷贝数据到 of 设备
    dd if=/dev/cdrom of=cd.iso      # 拷贝文件并转换成 iso 文件
    
  • 例:
    [[email protected] ~]# dd if=/dev/urandom of=f1 bs=1M count=1024    # 拷贝生成一个指定大小、随机内容的文件
    1024+0 records in
    1024+0 records out
    1073741824 bytes (1.1 GB) copied, 74.6221 s, 14.4 MB/s
    [[email protected] ~]# dd if=f1 of=f2 bs=1M                         # 拷贝文件,这也能测试磁盘的顺序读写速度
    1024+0 records in
    1024+0 records out
    1073741824 bytes (1.1 GB) copied, 7.92427 s, 136 MB/s
    

# scp

:安全拷贝协议(Secure copy protocol),用于在主机之间拷贝文件,基于 SSH 协议加密通信。

  • 命令:
    $ scp
          <file>... [email protected]:/root  # 将本机的文件拷贝到其它主机(需要通过 SSH 认证)
          [email protected]:/root/f1 /root   # 将其它主机的文件拷贝到本机的指定目录
          -C      # 传输数据流时启用压缩
          -P 22   # 指定 SSH 的端口
          -r      # 递归操作(用于拷贝目录)
    

# rsync

:用于在本机拷贝文件、目录,或跨主机拷贝。

  • 与 scp 相比:
    • rsync 服务默认采用 TCP 873 端口,且不是加密传输。不过可改为基于 SSH 协议传输。
    • rsync 将每个文件分成多个文件块传输,如果目标文件中已包含 md5 值相同的块,则不拷贝。因此支持断点续传、增量备份。
    • rsync 跨主机拷贝时,需要源主机、目标主机都安装了 rsync 。
  • 命令:
    $ rsync
            SRC... DEST             # 在本机拷贝文件(此时相当于 cp 命令)
            SRC... [USER@]HOST:DEST # 将本机的文件拷贝到其它主机
            [USER@]HOST:SRC... DEST # 将其它主机的文件拷贝到本机
            -e "ssh -p 22"          # 基于 SSH 协议加密传输
            -z                      # 传输数据流时启用压缩(不管是本机拷贝,还是跨主机拷贝)
    
            -a                      # 保留文件属性,且递归处理目录
            -P                      # 保留未完全拷贝的文件,并显示传输进度
    
            --ignore-existing       # 如果目标文件已存在,则不拷贝
            -u                      # --update ,如果目标文件已存在,且修改时间比源文件更新,则不拷贝
            --delete                # 删除目标目录比源目录多出的文件
            --inplace
            --append
    
    • 当 SRC 是目录时,如果以 / 结尾,则相当于 cp SRC/* DEST ,否则相当于 cp SRC DEST/SRC
    • 如果 DEST 目录不存在,则会自动创建。
  • 例:
    rsync -aP /tmp /data
    rsync -aP --inplace -e ssh  /root/f1 10.0.0.1:/root
    
  • rsync 将 src_file 拷贝文件到 dst_file 时:
    • 如果 dst_file 不存在(即目标文件路径未被占用),则从头拷贝 src_file 。
      • 拷贝时,默认先暂存到 DEST 目录下一个临时文件。比如拷贝 f1 文件时会暂存为 .f1.GRds8g 文件,等拷贝完才将它重命名为 f1 。如果拷贝中断,则删除该文件。
      • 启用 -P 选项时,即使未完全拷贝文件,rsync 就中断,也会将临时文件重命名为 dst_file 。此时该文件是不完整的, modify time 为 1970-01-01 。
    • 如果 dst_file 已存在,则检查其 md5 值、文件属性是否与 src_file 一致。
      • 如果相同,则不拷贝该文件。
      • 如果不同,则默认会从头拷贝 src_file 。
        • 例如事先用 cp 命令等其它方式拷贝该文件,即使已经拷贝完,也会因为文件的 modify time 与 src_file 不一致,导致 rsync 从头拷贝该文件。
        • 以下情况不会创建临时文件,而是直接保存到 dst_file 。
          • 启用 --inplace 选项时,会检查 dst_file 中各个文件块的 md5 值,如果与 src_file 不同,则拷贝。如果文件属性不同,则单独拷贝。
          • 启用 --append 选项时,会检查 dst_file 的长度,如果比 src_file 短,则拷贝缺少的字节到 dst_file 的末尾。因此不保证 dst_file 与 src_file 的长度、内容、文件属性一致。
        • 综上,如果想实现断点续传,避免从头拷贝文件,建议启用 -P 和 --inplace 选项。

# dump

dump、restore 命令用于备份本机的文件或目录,适用于 etx2、etx3、etx4 文件系统。

已淘汰不用
$ dump [option] <path>  # 备份指定的文件或目录
       -f <file>        # 保存为指定文件
       -[0-9]           # 设置备份级别
       -j               # 压缩为 bzip2 格式
  • 备份级别有 0~9 十种,0 是完全备份,1~9 都是增量备份。
    • 在备份整个分区或磁盘时才能使用增量备份。比如用 0 完全备份一次之后,可用 1 增量备份。下一次备份时,用 2 就是增量备份(级别加一),用 1 就是差异备份(覆盖之前的同级数据)。
  • dump 生成的备份文件并不是普通的压缩文件,还包含了一些备份信息,不能直接解压,只能被 restore 命令使用。
  • 例:
    dump -j -0f root.back.bz2 /root/
    
$ restore
         -f <file> # 指定备份文件(会根据其中的备份信息,还原到原路径)
         -r        # 用备份文件进行还原
         -t        # 显示备份文件的内容
         -C        # 比较当前文件与备份文件的差异(比如旧文件被修改、删除,但是增加新文件时不算差异)
  • restore 会生成一个 restoresymtable 文件,便于在增量备份时传递信息,可以删除。
  • 例:
    restore -tf root.back.bz2
    

# 压缩文件

# tar

:一种打包文件的格式,不会进行压缩,扩展名为 .tar 。

  • tar 命令也支持使用 gzip、bzip2、xz 压缩格式。
  • 打包命令:
    tar -cf <name>.tar <path>...          # 将指定文件或目录打包
        -c                                # 创建一个新文件
        -x                                # 提取文件。能根据文件头部的内容识别出 gzip、bzip2、xz 压缩格式,并自动解压
        -v                                # 显示处理过程的具体信息
        -f <name>.tar                     # 使用归档文件
        --exclude=./log*                  # 根据路径 pattern 将一些文件排除打包
        -g <snapshot>                     # 进行增量打包,生成一个快照文件
    
    • 打包文件时,如果输入的原路径是绝对路径,则会按绝对路径打包,生成多余的多层目录。因此,建议输入相对路径。
    • 如果已存在同名的包文件,则会覆盖它。
  • 解包命令:
    tar
        -xv <name>.tar                    # 解包到当前目录
              -C <dir>                    # 解包到指定目录(该目录必须已存在)
              [path]...                   # 只解压指定路径的文件(可以使用通配符)
              -p                          # 保留文件的原访问权限,否则将解压后文件的所有者变为当前用户。root 用户默认会启用该选项
        -tf <name>.tar                    # 不解包,只显示其中的文件列表。用 less xx.tar 命令也能查看文件列表
        -tf <name>.tar.gz | xargs rm -rf  # 删除解包生成的文件
    
  • 增量打包的示例:
    mkdir logs
    tar -g logs-snapshot -cvf logs-full-backup.tar logs/             # 先全量打包,作为起点
    touch logs/f1
    tar -g logs-snapshot -cvf logs-incremental-backup-1.tar logs/    # 增量打包
    touch logs/f2
    tar -g logs-snapshot -cvf logs-incremental-backup-2.tar logs/    # 增量打包
    
    • 用 -g 选项进行增量打包时,会在快照文件中记录此时打包的所有文件的 Modify time 。下一次增量打包时,如果有新增文件,或者老文件的 Modify time 更新了,才加入打包,否则生成的增量包为空。
    • 缺点是,增量打包时不能记录被删除的老文件。
    • 多次增量打包时,注意生成的 .tar.gz 包名不能重复,否则会覆盖之前的增量包。
    • 解包时,按照与打包时一致的顺序:
      tar -xvf logs-full-backup.tar
      tar -xvf logs-incremental-backup-1.tar
      tar -xvf logs-incremental-backup-2.tar
      

# gzip

:一种压缩文件格式,基于 Deflate 算法,扩展名为 .gz 。

  • 压缩命令:
    tar -zcvf <name>.tar.gz <path>...
        -z                              # 采用 gzip 格式
    
    • 压缩 tar 包时的扩展名为 .tar.gz ,可简写为 .tgz 。
  • 解压命令:
    tar -xf <archive>
    

# bzip2

:一种压缩文件格式,基于 Burrows–Wheeler 算法,扩展名为 .bz2 。

  • 安装:
    yum install bzip2
    
  • 命令:
    bzip2 <file>...
        -c            # --stdout ,将压缩或解压的文件输出到 stdout
        -z            # --compress ,压缩
        -d            # --decompress ,解压
        -k            # --keep ,在压缩、解压成功之后保留输入文件。默认会删除
    
    • bzip2 命令只支持压缩单个文件,因此通常用 tar 命令打包后压缩。默认将压缩后文件命名为 <name>.bz2
  • 压缩命令:
    tar -jcvf <name>.tar.bz2 <path>...
        -j            # 采用 bzip2 格式
    
  • 解压命令:
    tar -xf <archive>
    

# pbzip2

:一个命令行工具,以多线程方式进行 bzip2 压缩、解压。

  • 它会将文件数据划分为多个块,通过多线程并发处理。
  • 安装:
    yum install pbzip2
    
  • 压缩命令:
    tar -c <path> | pbzip2 -zk -p2 > <name>.tar.bz2
                          -b <int>    # 数据块的大小,单位为 100KB 。默认为 9 ,即 900KB
                          -m <int>    # 最多使用的内存量,单位为 MB 。默认为 100 ,即 100MB
                          -p <int>    # 使用的 CPU 数,即创建的线程数。默认会使用全部 CPU 核数
    
    • pbzip2 命令只支持压缩单个文件,且默认将压缩后文件输出到 stdout 。
  • 解压命令:
    pbzip2 -cdk -p2 <name>.tar.bz2  | tar -x
    

# xz

:一种压缩文件格式,基于 LZMA 算法,扩展名为 .xz 。

  • xz 命令与 bzip2 命令的用法相似。
  • 压缩命令:
    tar -Jcvf <name>.tar.xz <path>...
        -J          # 采用 xz 格式
    
  • 解压命令:
    tar -xf <archive>
    

# zip

:一种压缩文件格式,扩展名为 .zip 。

  • 支持多种压缩算法:

    • Deflate :Zip、GZip 的默认压缩算法,对应的解压算法称为 Inflate 。压缩率一般,但压缩、解压快。
    • Burrows–Wheeler :压缩率高,一般能压缩文件体积到 20% ,但压缩、解压慢。
    • LZMA :xz、7-Zip 的默认压缩算法,压缩率比 高。
  • 安装:

    yum install zip unzip
    
  • 压缩命令:

    $ zip <name>.zip <path>   # 压缩文件
          -r                  # 递归处理(用于处理目录)
          -s 500m             # --split-size ,将压缩包分割成多份,并设置每份的最大体积
          -i "*.py"           # --include ,只打包路径与 pattern 匹配的文件。注意 pattern 要用引号包住,避免先执行 * 去匹配文件名
          -x "logs/*" "*.log" # --exclude ,将一些文件排除打包。--exclude 比 --include 的优先级更高
          -P "..."            # 设置密码
          -q                  # 安静模式,不显示过程信息
    
    • 如果已存在同名的压缩包,则会加入其中。
      • 如果该压缩包中已存在同名的文件,则会覆盖它。
    • 例:批量压缩文件
      file_list=`ls *.mp4`
      for f in $file_list
      do
          zip $f.zip $f -P '******'
          rm -f $f
      done
      
  • 解压命令:

    $ unzip <name>.zip       # 解压一个压缩包
            [path]...        # 只解压指定路径的文件(可以使用通配符)
            -d <dir>         # 解压到指定目录(默认是当前目录)
            -o               # 当解压后的文件已存在时,直接覆盖
            -q               # 安静模式,不显示过程信息
    
            -l               # 不解压,而是显示其中的文件列表、修改时间。用 less xx.zip 命令也能查看文件列表
            -Z               # Zipinfo ,显示压缩包的详细信息,包括文件列表、模式、大小等
            -Z1              # 只显示文件列表
    
    • unzip 命令不支持直接解压分割成多份的压缩包。
      比如生成分割的压缩包:
      zip -s 10m -r tmp.zip /tmp    # 假设此时生成 tmp.z01  tmp.z02  tmp.zip ,其中 tmp.zip 是最后一份压缩包
      
      此时执行 unzip tmp.zip 会报错 bad zipfile offset ,需要用以下命令解压:
      zip -F tmp.zip --out tmp-fixd.zip   # 修复分割的压缩包,合并成一个包
      unzip tmp-fixd.zip
      

# 7-Zip

:一种压缩文件格式,扩展名为 .7z 。

  • 在加密方面:
    • Zip 采用传统的 ZipCrypto 算法,存在漏洞:如果知道文件中 12 字节的明文文本,则能大幅降低暴力破解的计算量。
    • 7-Zip 采用 AES-256 算法,又称为 7zAES:19 ,更安全。且支持将文件名也加密。

# 切割文件

# split

$ split [file] [prefix]   # 默认每隔 1000 行分割出一个子文件,子文件按 xaa、xab、xac 的格式命名,其中 prefix 默认为 x
        -l 10             # --lines ,每隔 10 行分割出一个子文件
        -b 10K            # --bytes ,每隔 10K Bytes 分割出一个子文件,单位可以是 K、M、G、T 等
        -d                # 让子文件从数字 00 开始编号

# csplit

$ csplit [file] [pattern]...  # 根据 pattern 分割文件。分割出的文件默认按 xx00、xx01、xx02 的格式命名
        -f xx                 # 设置子文件名称的前缀,默认为 xx
        -k                    # --keep-files ,当执行出错时,保留已生成的子文件。默认会全部删除
        -s                    # --silent ,不打印每个子文件的 bytes 体积。默认会打印
        --suppress-matched    # 保存子文件时,排除匹配行
  • 例:
    csplit f1  2          # pattern 为数字时,表示从第 n 行分割出两个子文件,并且第 n 行保存到后一个子文件
    csplit f1  3 6 9      # 可指定多个 pattern ,这会分割多次
    csplit f1  /Hello/    # 寻找与 pattern 正则匹配的行,从每个匹配行分割文件,并且每个匹配行保存到后一个子文件
    csplit f1  %^Hello%   # %pattern% 表示排除匹配行之前的内容,将从匹配行开始的内容保存为子文件
    csplit f1  "/^Hello World/" {5}   # {n} 表示将前一个 pattern 重复执行 n 次,如果找不到匹配行则报错
    csplit f1  "/^Hello World/" {*}   # {*} 表示将前一个 pattern 重复执行尽可能多次,直到找不到匹配行。至少会生成一个子文件
    

# truncate

$ truncate [file]...  # 将文件截断为指定大小。多余的空间会被丢弃,缺少的空间会用空字节填补
          -s 10M      # 保留从文件第一个字节开始的 10M 内容

# 其它

# md5sum

$ md5sum [file]...    # 计算文件内容的 md5 哈希值
  • 例:
    [[email protected] ~]# echo Hello | md5sum
    09f7e02f1290be211da707a266f153b3  -
    
  • 当文件内容改变任一字节时,哈希值都会变化。但文件属性(比如修改时间)变化时,哈希值不变。
  • 另外还有 sha1sum、sha256sum、sha512sum 等其它哈希算法的命令,用法同理。

# 随机数

  • 类 Unix 系统会收集一些环境噪声(比如硬件中断的时间戳的最低几位),暂存到一个熵池(entropy pool)中,用于生成随机数。
  • 查看系统熵池的大小,单位为 bits :
    [[email protected] ~]# cat /proc/sys/kernel/random/entropy_avail
    3754
    
  • 用户可通过以下两个字符设备文件,获取随机数:
    • /dev/random :消耗熵池来产生随机数,随机性很高,但是熵池不足时会阻塞读取它的进程。
    • /dev/urandom :重复使用熵池来产生随机数,随机性略低,但一般足够安全。一般读取速度为几十 MB/s ,不会阻塞。
    • 例:
      head -c 10m /dev/urandom > f1                            # 生成一个指定大小、随机内容的文件
      cat /dev/urandom | tr -cd A-Za-z0-9 | head -c 12 ; echo  # 生成随机字符串
      echo $[`cat /dev/urandom | tr -cd 0-9 | head -c 2`%5]    # 生成小于 5 的随机数