split 切割大文件

#!/bin/bash

# 生产环境磁盘格式化与挂载脚本
# 功能:安全地格式化磁盘为XFS,创建挂载点,配置自动挂载

set -euo pipefail  # 启用严格模式

SCRIPT_NAME=$(basename "$0")
LOG_FILE="/var/log/disk_init.log"

# 日志函数
log() {
    local level=$1
    shift
    local message="$*"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}

# 错误处理函数
error_exit() {
    log "ERROR" "$1"
    exit "${2:-1}"
}

# 使用说明
usage() {
    cat << EOF
Usage: $SCRIPT_NAME <disk_device>
Example: $SCRIPT_NAME /dev/vdb

安全注意事项:
1. 此脚本会永久擦除指定磁盘上的所有数据
2. 请确认磁盘设备路径正确,避免误操作系统盘
3. 建议在生产环境使用前在测试环境验证
EOF
}

# 参数验证
validate_parameters() {
    if [ $# -ne 1 ]; then
        usage
        error_exit "参数错误:需要且只能指定一个磁盘设备参数" 1
    fi

    local disk=$1

    # 检查磁盘设备是否存在且为块设备
    if [ ! -b "$disk" ]; then
        error_exit "磁盘设备 $disk 不存在或不是块设备" 2
    fi

    # 防止误操作系统盘或其他关键磁盘
    local critical_disks=("/dev/sda" "/dev/vda" "/dev/nvme0n1" "/dev/mmcblk0")
    for critical_disk in "${critical_disks[@]}"; do
        if [[ "$disk" == "$critical_disk"* ]]; then
            error_exit "安全警告:$disk 可能是系统盘,禁止操作!" 3
        fi
    done

    # 检查磁盘是否已被挂载
    if mount | grep -q "^$disk"; then
        log "WARNING" "磁盘 $disk 当前已被挂载,尝试卸载..."
        safe_umount "$disk"
    fi
}

# 安全卸载函数
safe_umount() {
    local disk=$1
    local mount_point=$(mount | grep "^$disk" | awk '{print $3}')
    
    if [ -n "$mount_point" ]; then
        log "INFO" "卸载磁盘 $disk (挂载点: $mount_point)"
        
        # 检查是否有进程正在使用挂载点
        if lsof "$mount_point" &>/dev/null; then
            log "WARNING" "有进程正在使用 $mount_point,尝试终止相关进程..."
            fuser -km "$mount_point"  # 终止使用该挂载点的进程
            sleep 2
        fi
        
        if ! umount "$disk"; then
            error_exit "无法卸载磁盘 $disk" 4
        fi
        log "INFO" "卸载成功"
    fi
}

# 检查必要工具
check_dependencies() {
    local dependencies=("blkid" "mkfs.xfs" "lsof" "fuser")
    
    for cmd in "${dependencies[@]}"; do
        if ! command -v "$cmd" &>/dev/null; then
            error_exit "缺少必要工具: $cmd,请先安装" 5
        fi
    done
}

# 确认操作
confirm_operation() {
    local disk=$1
    
    cat << EOF

!!! 安全警告 !!!
您即将执行以下操作:
1. 磁盘设备: $disk
2. 操作: 格式化磁盘为XFS文件系统
3. 挂载点: /export
4. 数据: 该磁盘上的所有数据将被永久删除!

请确认:
- 您已备份重要数据
- 磁盘设备路径正确
- 这不是系统盘

EOF
    
    read -p "确认继续操作?(输入 'YES' 继续): " confirmation
    if [ "$confirmation" != "YES" ]; then
        log "INFO" "用户取消操作"
        exit 0
    fi
}

# 格式化磁盘
format_disk() {
    local disk=$1
    
    log "INFO" "开始格式化磁盘 $disk 为 XFS 文件系统"
    
    # 检查磁盘是否已被使用
    if blkid "$disk" &>/dev/null; then
        local current_fs=$(blkid -s TYPE -o value "$disk" 2>/dev/null || echo "unknown")
        log "WARNING" "磁盘 $disk 已有文件系统: $current_fs"
    fi
    
    # 使用更安全的格式化选项
    if ! mkfs.xfs -f -i size=512 -l size=128m -d su=64k,sw=4 "$disk"; then
        error_exit "磁盘格式化失败" 6
    fi
    
    log "INFO" "磁盘格式化成功"
}

# 准备挂载点
prepare_mountpoint() {
    local mount_point="/export"
    
    # 检查挂载点是否已被使用
    if mount | grep -q " $mount_point "; then
        local mounted_device=$(mount | grep " $mount_point " | awk '{print $1}')
        log "WARNING" "挂载点 $mount_point 已被 $mounted_device 使用"
        
        if ! umount "$mount_point"; then
            error_exit "无法卸载现有的挂载点 $mount_point" 7
        fi
    fi
    
    # 创建挂载点目录
    mkdir -p "$mount_point"
    if [ $? -ne 0 ]; then
        error_exit "创建挂载点目录失败" 8
    fi
    
    log "INFO" "挂载点准备完成: $mount_point"
}

# 挂载磁盘
mount_disk() {
    local disk=$1
    local mount_point="/export"
    
    log "INFO" "挂载磁盘 $disk 到 $mount_point"
    
    if ! mount "$disk" "$mount_point"; then
        error_exit "磁盘挂载失败" 9
    fi
    
    # 验证挂载是否成功
    if ! mountpoint -q "$mount_point"; then
        error_exit "挂载验证失败" 10
    fi
    
    log "INFO" "挂载成功"
}

# 配置自动挂载
configure_fstab() {
    local disk=$1
    local mount_point="/export"
    
    log "INFO" "配置自动挂载"
    
    # 获取UUID
    local uuid=$(blkid -s UUID -o value "$disk")
    if [ -z "$uuid" ]; then
        error_exit "获取磁盘UUID失败" 11
    fi
    
    local fstab_entry="UUID=$uuid $mount_point xfs defaults,noatime,nodiratime 0 0"
    
    # 备份fstab文件
    cp /etc/fstab "/etc/fstab.backup.$(date +%Y%m%d_%H%M%S)"
    
    # 移除已有的相关条目
    sed -i.bak "\|$mount_point|d" /etc/fstab
    sed -i.bak "\|^UUID=$uuid|d" /etc/fstab
    
    # 添加新条目
    echo "$fstab_entry" >> /etc/fstab
    
    # 验证fstab语法
    if ! mount -a &>/dev/null; then
        # 恢复备份
        cp /etc/fstab.bak /etc/fstab
        error_exit "fstab 配置错误,已恢复备份" 12
    fi
    
    log "INFO" "自动挂载配置完成 (UUID: $uuid)"
}

# 创建数据目录
create_data_directory() {
    local data_dir="/export/Data"
    
    mkdir -p "$data_dir"
    chmod 755 "$data_dir"
    
    # 设置合适的权限
    if [ ! -d "$data_dir" ]; then
        error_exit "创建数据目录失败" 13
    fi
    
    log "INFO" "数据目录创建完成: $data_dir"
}

# 显示摘要信息
show_summary() {
    local disk=$1
    local mount_point="/export"
    
    cat << EOF

操作完成摘要:
==============
磁盘设备: $disk
文件系统: $(blkid -s TYPE -o value "$disk")
UUID: $(blkid -s UUID -o value "$disk")
挂载点: $mount_point
数据目录: $mount_point/Data
挂载状态: $(mount | grep "^$disk" && echo "已挂载" || echo "未挂载")

磁盘空间信息:
==============
$(df -h "$mount_point")

EOF
}

# 主函数
main() {
    log "INFO" "脚本开始执行: $SCRIPT_NAME $*"
    
    # 检查依赖
    check_dependencies
    
    # 验证参数
    validate_parameters "$@"
    
    local disk=$1
    
    # 用户确认
    confirm_operation "$disk"
    
    # 执行操作序列
    format_disk "$disk"
    prepare_mountpoint
    mount_disk "$disk"
    configure_fstab "$disk"
    create_data_directory
    
    # 显示结果
    show_summary "$disk"
    
    log "INFO" "脚本执行完成"
}

# 信号处理
trap 'error_exit "脚本被用户中断" 130' INT TERM

# 执行主函数
main "$@"

split 命令是 Linux 系统中一个非常有用的工具,用于将大文件分割成多个较小的文件。这种方法在处理大文件时非常有用,特别是在需要传输大文件或在磁盘空间有限的情况下下面是 split 命令的详细解释,包括其选项和用法。

基本用法
split 命令的基本语法如下:

split [选项] [输入文件] [输出文件前缀]

输入文件:要分割的文件。如果省略,则从标准输入读取。
输出文件前缀:分割后的文件将以此前缀命名,后跟一个字母或数字后缀(默认情况下,后缀从 aa 开始,依次递增)。
常用选项
-l, --lines=行数:按行数分割文件。例如,-l 1000 表示每 1000 行分割一次。
-b, --bytes=大小:按字节大小分割文件。例如,-b 10M 表示每 10MB 分割一次。
-C, --line-bytes=大小:按行分割文件,但每个输出文件的大小不超过指定的字节数。
-a, --suffix-length=长度:指定后缀的长度,默认为 2。
-d, --numeric-suffixes:使用数字后缀而不是字母后缀。
–additional-suffix=后缀:为每个输出文件添加额外的后缀。
–filter=命令:在写入输出文件之前,通过指定的命令过滤输入。
示例
按行数分割文件

split -l 1000 largefile.txt split_file_

这将 largefile.txt 按每 1000 行分割成多个文件,文件名从 split_file_aa 开始,依次递增。

按字节大小分割文件

split -b 10M largefile.txt split_file_

这将 largefile.txt 按每 10MB 分割成多个文件,文件名从 split_file_aa 开始,依次递增。

使用数字后缀

split -d -l 1000 largefile.txt split_file_

这将 largefile.txt 按每 1000 行分割成多个文件,文件名从 split_file_00 开始,依次递增。

添加额外的后缀

split -l 1000 --additional-suffix=.txt largefile.txt split_file_

这将 largefile.txt 按每 1000 行分割成多个文件,文件名从 split_file_aa.txt 开始,依次递增。

合并分割的文件
使用 cat 命令可以轻松地将分割的文件合并回原文件:

cat split_file_* > largefile.txt

注意事项
文件名冲突:确保输出文件的前缀不会与现有文件名冲突,以避免覆盖重要数据。
文件顺序:当合并文件时,确保按正确的顺序合并文件,特别是当使用字母后缀时。
性能考虑:分割大文件可能会消耗大量的磁盘 I/O 和 CPU 资源,特别是在按行分割时,因为需要读取和处理每一行。
通过 split 命令,你可以有效地管理大文件,特别是在需要传输或存储大文件时。了解和使用 split 的各种选项,可以根据不同的需求灵活地分割文件。

connection

在使用网络应用程序时,遇到 Connection refused 和 Connection timed out 错误是比较常见的。这两个错误通常指示不同类型的问题。以下是它们可能的原因和一些解决方案:

Connection Refused
原因:

服务未运行:目标服务器上的服务(如 SSH、HTTP 等)未启动。
端口未开放:请求连接的端口在目标服务器上没有监听服务。
防火墙阻止:防火墙配置阻止了连接请求。
错误的 IP 地址或端口:连接请求使用了错误的 IP 地址或端口。
服务器配置错误:服务器配置不正确,导致服务无法正确响应连接请求。
解决方案:

检查目标服务器上的服务是否正在运行。例如,使用 systemctl status <service> 检查服务状态。
确认服务正在监听正确的端口。使用 netstat -tuln 或 ss -tuln 查看监听的端口。
检查防火墙设置,确保允许所需的端口通过。使用 iptables 或 firewalld 进行配置。
确认使用的 IP 地址和端口是正确的。
查看服务器日志文件以获取更多错误信息。
Connection Timed Out
原因:

网络不通:网络连接中断或网络路径不通。
服务器过载:服务器负载过高,无法及时响应请求。
防火墙配置:防火墙规则可能导致连接被丢弃而不是拒绝。
网络延迟:网络延迟过高,导致连接请求超时。
路由问题:网络路由配置错误或不稳定。
解决方案:

使用 ping 或 traceroute 检查网络连通性和路径。
检查服务器负载,使用 top 或 htop 查看服务器资源使用情况。
检查防火墙配置,确保规则不会无意中丢弃合法流量。
如果网络延迟是问题的根源,考虑优化网络路径或使用更快的网络连接。
检查路由配置,确保没有错误或不稳定的路由。
总结
Connection Refused 通常意味着你的请求成功到达了目标服务器,但由于某种原因被服务器拒绝。
Connection Timed Out 通常意味着请求无法在规定的时间内到达目标服务器,可能是由于网络问题或服务器未响应。
通过这些检查和调整,你应该能够诊断并解决大多数 Connection refused 和 Connection timed out 问题。
在 Linux 中,去除字符串首尾的空白字符(包括空格、制表符、换行符等)可以通过多种方法实现。这里介绍几种常用的方法,包括使用 bash 内置命令、awk、sed 和 xargs 等工具。

  1. 使用 xargs
    xargs 是一个非常方便的工具,用于构建和执行命令行。它可以用来去除字符串的首尾空白字符。
            
echo "   这是一个测试字符串   " | xargs

这将输出:

这是一个测试字符串

  1. 使用 awk
    awk 是一个强大的文本处理工具,可以用来处理和格式化文本数据。
            
echo "   这是一个测试字符串   " | awk '{print $0}'

这也会输出:

这是一个测试字符串

  1. 使用 sed
    sed 是一个流编辑器,可以用来过滤和转换文本。
            
echo "   这是一个测试字符串   " | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'

这将去除字符串首尾的所有空白字符,输出:

这是一个测试字符串

  1. 使用 bash 参数扩展
    在 bash 脚本中,可以使用参数扩展来去除变量值的首尾空白字符。
            
str="   这是一个测试字符串   "
str="${str#"${str%%[![:space:]]*}"}"   # 去除前导空白
str="${str%"${str##*[![:space:]]}"}"  # 去除尾随空白
echo "$str"

这也会输出:

这是一个测试字符串

  1. 使用 tr 命令
    tr 命令可以用来删除或替换字符。
echo "   这是一个测试字符串   " | tr -d '[:space:]'

但是,这个命令会删除字符串中的所有空白字符,包括中间的空格。如果你只想去除首尾的空白字符,上述 xargs、awk、sed 或 bash 参数扩展的方法会更合适。

选择合适的方法
xargs 是最简单直接的方法,适合快速去除字符串首尾的空白字符。
awk 和 sed 提供了更灵活的文本处理能力,适合需要进行更复杂文本处理的场景。
bash 参数扩展 适合在 bash 脚本中使用,提供了一种内置的方式来处理字符串。
tr 适合删除或替换特定字符,但不适合仅去除首尾空白。
根据你的具体需求和使用场景选择最合适的方法。对于大多数简单的去除首尾空白字符的需求,xargs 是一个非常方便的选择。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容