第4章 Shell脚本基础与电商数据自动化处理实操

4.1 Shell脚本在电商数据分析中的核心用处

我刚做数据分析的时候,每天重复做几件事:早上登录服务器,把昨天的订单文件复制一份到分析目录,解压运营发来的数据包,改名,跑清洗脚本,然后把处理结果导出发给运营。每天至少花40分钟在这些机械、无技术含量的操作上,挤占了大量用于数据分析的时间。

后来一个运维大哥跟我说:“你这些重复操作,写个脚本就能自动跑,干嘛天天手动敲?”我这才开始接触Shell脚本。说实话,学完第一个月,我每天的重复工作时间从40分钟降到了5分钟——脚本一键执行,不用盯着屏幕等每一步完成。多出来的时间,我可以多分析几个店铺的经营数据,或者早点下班陪伴家人。

Shell脚本在电商数据分析里,核心就解决三类高频痛点问题,不用学复杂语法,能落地、能省时间就是关键:

  • 批量操作:同时处理10个甚至20个店铺的报表,不用一个个文件手动修改、复制,避免重复劳动和人为失误

  • 定时任务:日报、周报、月度报表设置好定时执行,不用每天记着去触发,到点自动生成结果

  • 流程串联:把“下载数据→解压→清洗→归档→备份”整个流程串成一个命令,一键完成,减少操作步骤

这一章不讲复杂的脚本语法,不搞理论堆砌,只讲电商数据分析师每天都能用上的基础内容,学完就能写脚本、省时间。


4.2 Shell脚本基础认知

4.2.1 什么是Shell脚本

简单说,Shell脚本就是把你在Linux命令行里敲的一串命令,按顺序写到一个文本文件里,给文件添加执行权限后,让系统按顺序自动执行。就像你给电脑写了一份“工作清单”,它照着清单一步步完成,不用你全程手动操作。

一个最简脚本长这样(保存为test.sh):

#!/bin/bash
# 这是注释,不会被执行,用于说明脚本用途
echo "开始处理订单数据"  # 打印提示信息
ls -l /data/orders/      # 查看订单目录下的文件

重点说明:

  • 第一行#!/bin/bash叫“shebang”,必须写在脚本第一行,作用是告诉系统用哪个解释器来执行这个脚本(固定写法,不用改)。

  • #开头的是注释,用于说明脚本功能、步骤,方便自己后续查看或他人复用,不影响脚本执行。

  • 后面每一行都是一个Linux命令,系统会从上到下依次执行。

4.2.2 脚本的适用场景

不是所有事情都需要写脚本,浪费时间反而得不偿失。我总结了一个简单的判断标准,新手可以直接套用:

  • 做一次:比如偶尔下载一次行业数据,手动敲命令就行,没必要写脚本。

  • 做三次以上:比如连续三天处理不同日期的订单数据,操作步骤完全一样,就可以考虑写脚本,后续再用直接调用。

  • 每天/每周都要做:比如每天备份订单、每周汇总店铺报表,这些高频重复操作,必须写脚本,解放双手。

比如每天备份昨天的订单数据、每周汇总10个店铺的销售报表、每月解压运营发来的数据包,这些场景都特别适合写成脚本,一次编写,多次复用。


4.3 Shell脚本核心基础语法

核心语法只讲5个:变量、位置参数、条件判断、循环、基础函数,都是电商场景高频用到的,不用死记硬背,结合场景练2次就能掌握。

4.3.1 变量:让脚本更灵活

变量就是给一串数据(比如路径、日期)起个简单好记的名字,后续脚本中反复用到时,不用重复写完整内容,修改也只需要改一处,让脚本更灵活、更易维护。

基础用法(核心:等号两边不能有空格):

# 定义变量(格式:变量名=值,等号两边无空格)
data_path="/data/orders"  # 定义订单数据目录路径
date_str="20251128"       # 定义日期

# 使用变量(格式:$变量名,前面加$符号)
echo $data_path           # 打印订单目录路径
ls -l $data_path/$date_str/  # 查看指定日期的订单文件

电商场景:批量处理不同日期的订单

假设我要处理连续一周的订单数据,每天的操作步骤完全一样,只是日期不同,用变量就能快速切换日期,不用每次修改整个脚本:

#!/bin/bash
# 定义日期变量,修改这里就能切换处理的日期
order_date="20251128"
# 定义源目录(原始订单数据存放处)和目标目录(分析用数据存放处)
source_dir="/data/orders/$order_date"
target_dir="/data/analysis/$order_date"

# 打印提示信息,方便查看当前处理的日期和路径
echo "处理日期:$order_date"
echo "源目录(原始数据):$source_dir"
echo "目标目录(分析数据):$target_dir"

# 执行复制操作,将原始数据复制到分析目录
cp -r $source_dir $target_dir
echo "$order_date 订单数据已复制完成"

运行脚本后,只需要修改order_date这一个变量的值(比如改成20251129、20251130),就能切换不同日期的数据处理,高效又不易出错。

4.3.2 位置参数:从命令行传值,更便捷

比变量更方便的是“位置参数”——运行脚本时,直接在脚本名称后面传入值,脚本里用$1$2$3来接收($1是第一个传入的值,$2是第二个,以此类推),不用每次修改脚本里的变量。

脚本内容(保存为process.sh):

#!/bin/bash
# $1 接收命令行传入的第一个参数(日期)
order_date=$1
# 打印当前处理的日期
echo "正在处理 $order_date 的订单数据"
# 执行复制操作
cp /data/orders/$order_date/*.csv /data/analysis/$order_date/
echo "$order_date 订单数据已复制完成"

运行方式(在命令行传入日期参数):

./process.sh 20251128

输出结果:正在处理 20251128 的订单数据20251128 订单数据已复制完成

电商场景:处理任意日期的订单

每天处理前一天的订单,只需要在运行脚本时传入对应日期,不用修改脚本内容,适合高频重复操作:

#!/bin/bash
# 用法:./daily_process.sh 20251128(后面跟日期参数)
date=$1  # 接收命令行传入的日期
# 检查日期参数是否传入,避免报错
if [ -z "$date" ]; then
    echo "错误:请传入日期参数,用法:./daily_process.sh 20251128"
    exit 1
fi
# 复制指定日期的订单文件到分析目录
cp /data/orders/$date/*.csv /data/analysis/$date/
echo "$date 订单数据已复制完成"

实操避坑提醒:变量名不要带空格,不要用-(横线),推荐用下划线_(比如order_date,不要写order-date)。我第一次写变量用了order-date,脚本一直报错,找了半天才发现变量名不能用横线,这是新手最容易踩的坑。

4.3.3 条件判断:让脚本学会“做决策”

实际处理数据时,经常需要判断“文件是否存在”“目录是否为空”,如果不判断,文件不存在时脚本会报错、继续执行无效操作,导致数据混乱。if条件判断语句,就能让脚本根据不同情况做不同的操作,更智能、更稳健。

基础语法(核心:条件两边有空格,then换行,fi结尾):

if [ 条件 ]; then
    # 条件成立时,执行这里的命令
else
    # 条件不成立时,执行这里的命令
fi

常用条件判断(电商场景高频):

  • -f 文件名:判断文件是否存在(比如判断订单文件是否存在)

  • -d 目录名:判断目录是否存在

  • -z "$变量":判断变量是否为空(比如判断是否传入日期参数)

电商场景1:检查数据文件是否存在再处理

处理订单数据前,先判断文件是否存在,避免文件缺失导致脚本报错、执行无效操作:

#!/bin/bash
date=$1  # 接收命令行传入的日期
# 定义订单文件路径
file_path="/data/orders/$date/order_detail.csv"

# 判断文件是否存在
if [ -f "$file_path" ]; then
    echo "找到 $date 的订单文件,开始复制"
    cp $file_path /data/analysis/
else
    echo "错误:未找到 $date 的订单文件(路径:$file_path)"
    exit 1  # 退出脚本,不再执行后续操作
fi

电商场景2:检查目录是否为空,避免无效处理

待处理目录为空时,脚本直接提示,不执行后续操作,节省资源:

#!/bin/bash
# 待处理文件目录
dir="/data/to_process"
# 判断目录是否为空(2>/dev/null 避免目录不存在时的报错)
if [ -z "$(ls -A $dir 2>/dev/null)" ]; then
    echo "目录 $dir 为空,无需处理"
    exit 0  # 正常退出脚本
else
    echo "发现待处理文件,开始处理"
    # 后续处理逻辑(比如复制、重命名)
    cp $dir/*.csv /data/processed/
    echo "处理完成"
fi

4.3.4 循环:批量处理的核心,一次操作搞定多个文件/店铺

循环是Shell脚本里最实用的功能,能自动重复执行同一套操作,比如批量处理10个店铺的报表、批量重命名几十个文件、批量创建12个月的目录,不用手动逐个操作,极大提升效率。

for循环基础语法(电商场景最常用):

for 变量 in 列表; do
    # 对列表中的每个元素,执行这里的操作
done

电商场景1:批量处理10个店铺的报表

有10个店铺的日报文件,需要统一复制到处理目录,用循环一键完成:

#!/bin/bash
# 定义店铺列表(用括号包裹,逗号分隔)
shops=("shop01" "shop02" "shop03" "shop04" "shop05" "shop06" "shop07" "shop08" "shop09" "shop10")

# 循环处理每个店铺
for shop in "${shops[@]}"; do
    echo "正在处理 $shop 的日报"
    # 复制该店铺的日报文件到处理目录,并重命名(加上日期)
    cp /data/raw/${shop}_daily.csv /data/processed/${shop}_$(date +%Y%m%d)_processed.csv
done
echo "所有店铺日报处理完成"

电商场景2:批量重命名文件

待处理目录下有多个CSV文件,需要统一加上“processed_”前缀,方便区分已处理和未处理文件:

#!/bin/bash
# 进入待处理文件目录
cd /data/to_process
# 循环目录下所有CSV文件(*.csv 匹配所有CSV文件)
for file in *.csv; do
    # 定义新文件名(前缀+原文件名)
    newname="processed_$file"
    # 重命名文件
    mv "$file" "$newname"
    echo "已重命名:$file -> $newname"
done
echo "所有文件重命名完成"

电商场景3:批量创建月度目录

提前创建2025年12个月的分析目录,方便后续按月份存放数据,不用手动逐个创建:

#!/bin/bash
# 循环1-12月(01-12,保证格式统一)
for month in 01 02 03 04 05 06 07 08 09 10 11 12; do
    # 创建多级目录(-p 确保父目录不存在时也能创建)
    mkdir -p /data/analysis/2025/$month
    echo "已创建目录:/data/analysis/2025/$month"
done
echo "12个月目录创建完成"

实操避坑提醒:如果文件名或目录名带空格(比如“shop 01.csv”),变量一定要加双引号,写成"$file"。我吃过一次亏——文件名有空格,没加引号,mv命令把文件名拆成了两个参数,导致文件被改名改乱,后续排查花了很久。

4.3.5 基础函数:封装常用操作,避免重复编写

如果一段操作逻辑要在脚本里反复使用(比如写日志、检查目录是否存在),可以把这段逻辑封装成“函数”,后续使用时直接调用函数名,不用重复编写相同的命令,让脚本更简洁、更易维护。

基础语法

函数名() {
    # 函数体(要重复执行的操作)
    命令1
    命令2
}

# 调用函数(直接写函数名)
函数名

电商场景:封装日志写入函数

脚本执行过程中,需要多次写入日志(记录操作时间、操作内容),封装成函数,不用每次都写日期格式:

#!/bin/bash
# 定义日志函数(参数$1 是要写入的日志内容)
log_message() {
    # 写入日志:时间戳 + 日志内容,追加到日志文件
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> /data/logs/process.log
}

# 调用日志函数,记录操作
log_message "开始处理订单数据"
# 执行复制操作
cp /data/orders/*.csv /data/analysis/
log_message "订单数据复制完成"
# 执行压缩操作
tar -czf /data/backup/orders_backup.tar.gz /data/analysis/
log_message "订单数据备份完成"

echo "所有操作执行完毕,详细日志请查看 /data/logs/process.log"

这样每次需要写日志,直接调用log_message "日志内容"即可,不用重复写date命令和日志路径,简洁又高效。


4.4 脚本的创建、编辑、运行全流程(新手必看)

学会语法后,更重要的是掌握脚本从创建到运行、调试的完整流程,新手按步骤来,不会出错。

4.4.1 步骤1:创建脚本文件

touch命令创建一个后缀为.sh的文件(.sh是Shell脚本的标准后缀,方便识别):

touch /home/yourname/daily_backup.sh

说明:/home/yourname/是脚本存放路径,可根据自己的习惯修改(比如/data/scripts/);daily_backup.sh是脚本名称,建议命名有意义,比如“订单备份脚本”就叫daily_backup.sh

4.4.2 步骤2:编辑脚本内容

用Vim编辑器打开脚本文件(新手也可以用其他编辑器,比如nano):

vim /home/yourname/daily_backup.sh

i键进入编辑模式,写入脚本内容(以最简单的每日订单备份脚本为例):

#!/bin/bash
# 每日订单备份脚本(用途:备份当天的订单数据到备份目录)
# 自动获取当天日期(格式:20251128)
date=$(date +%Y%m%d)
# 备份订单数据(复制当天的订单文件到备份目录)
cp /data/orders/$date/*.csv /data/backup/$date/
# 打印备份完成提示
echo "$date 订单数据备份完成"

编辑完成后,按Esc键,输入:wq,按回车保存并退出Vim。

4.4.3 步骤3:添加执行权限

刚创建的脚本文件没有执行权限,无法直接运行,需要用chmod命令添加执行权限(第3章讲过的权限命令,这里直接复用):

chmod +x /home/yourname/daily_backup.sh

预期结果:用ls -l /home/yourname/daily_backup.sh查看,权限会变成-rwxr-xr-x,末尾有x(执行权限),说明权限添加成功。

4.4.4 步骤4:运行脚本

脚本添加执行权限后,有两种运行方式,新手推荐第一种:

方式一:直接运行(需要执行权限)

cd /home/yourname/  # 进入脚本所在目录
./daily_backup.sh   # 直接运行脚本(./ 表示当前目录)

方式二:用bash运行(不需要执行权限)

如果忘记添加执行权限,或者不想添加,也可以用bash命令直接运行(跳过权限检查):

bash /home/yourname/daily_backup.sh

运行后,会输出20251128 订单数据备份完成(日期会自动获取当天),说明脚本运行成功。

4.4.5 步骤5:调试脚本(脚本报错怎么办?)

新手写脚本,难免会报错(比如变量写错、路径错误),不知道问题出在哪,这时候用-x参数调试,能看到脚本每一步的执行过程和变量值,快速定位问题。

调试命令(两种方式均可):

bash -x daily_backup.sh  # 直接调试当前目录的脚本
bash -x /home/yourname/daily_backup.sh  # 用绝对路径调试

调试时,会输出每一条命令的执行过程(前面带+号)和变量的具体值,比如变量date的值是20251128,路径是否正确,命令是否执行成功,一目了然。

常见问题处理(新手高频)

  • 报“Permission denied”(权限不足):没给脚本添加执行权限,用chmod +x 脚本路径解决。

  • 报“command not found”(命令找不到):要么是命令写错了(比如cp写成cp1),要么是脚本里用了cd切换路径,但路径不存在,导致后续命令无法执行。

  • 变量没生效:检查变量名是否写错(比如date_str写成dateStr),或者使用变量时没加$(比如echo date_str,正确是echo $date_str)。

  • 脚本执行一半报错停止:用bash -x调试,查看报错的命令和变量值,大概率是路径错误或文件不存在。


4.5 电商数据分析高频脚本实用技巧(直接套用)

结合电商数据分析的高频场景,整理了4个实用技巧,新手可以直接复制到脚本里使用,不用自己编写。

4.5.1 技巧1:自动获取昨天的日期(每日报表必备)

每天处理前一天的订单数据,不用手动输入日期,脚本自动获取昨天的日期,适合设置定时任务:

# 自动获取昨天的日期(格式:20251128)
yesterday=$(date -d "yesterday" +%Y%m%d)
echo "昨天的日期:$yesterday"

电商场景:每天早上自动处理昨天的订单

#!/bin/bash
# 自动获取昨天的日期
yesterday=$(date -d "yesterday" +%Y%m%d)
# 定义源目录(昨天的订单数据)和目标目录(分析目录)
source_dir="/data/orders/$yesterday"
target_dir="/data/analysis/$yesterday"

# 检查源目录是否存在(避免日期错误导致目录不存在)
if [ -d "$source_dir" ]; then
    # 递归复制目录下所有文件
    cp -r $source_dir $target_dir
    echo "$yesterday 订单数据已复制到分析目录"
else
    echo "警告:$yesterday 的订单目录不存在,请检查日期或数据是否上传"
fi

4.5.2 技巧2:批量删除7天前的临时文件(清理空间必备)

处理数据时会产生很多临时文件(比如解压后的临时数据、日志备份),占用服务器空间,用这条命令批量删除7天前的临时文件,配合定时任务自动清理:

# 批量删除7天前的临时文件(/tmp/order_temp/ 是临时文件目录,可修改)
# -type f:只删除文件,不删除目录;-mtime +7:修改时间超过7天;-delete:删除
find /tmp/order_temp/ -type f -mtime +7 -delete
echo "7天前的临时文件已删除"

4.5.3 技巧3:检查磁盘空间(避免空间不足导致脚本失败)

电商数据文件通常很大,磁盘空间不足会导致脚本执行失败(比如无法复制、解压文件),添加磁盘空间检查,提前预警:

#!/bin/bash
# 检查/data分区的使用率(电商数据通常存放在/data分区)
# df -h 查看磁盘使用率;awk 'NR==2 {print $5}' 提取第二行第五列(使用率,如80%);sed 's/%//' 去掉%号
usage=$(df -h /data | awk 'NR==2 {print $5}' | sed 's/%//')

# 如果使用率超过85%,提示警告(可根据实际情况修改阈值)
if [ $usage -gt 85 ]; then
    echo "警告:/data 分区使用率已达 $usage%,请及时清理空间,避免影响脚本执行"
    # 可选:触发自动清理脚本(比如删除临时文件)
    # find /tmp/order_temp/ -type f -mtime +7 -delete
    # echo "已自动删除7天前的临时文件,释放部分空间"
fi

4.5.4 技巧4:带时间戳的日志记录(合规追溯必备)

脚本执行日志需要带时间戳,方便后续排查问题、合规审计,封装成函数,直接调用:

#!/bin/bash
# 定义日志文件(带当天日期,避免日志文件过大)
log_file="/data/logs/backup_$(date +%Y%m%d).log"

# 日志函数(带时间戳)
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $log_file
}

# 调用日志函数,记录每一步操作
log "开始执行订单备份脚本"
yesterday=$(date -d "yesterday" +%Y%m%d)
cp -r /data/orders/$yesterday /data/backup/$yesterday
log "昨天($yesterday)的订单数据备份完成"
log "备份目录:/data/backup/$yesterday"

echo "备份完成,详细日志请查看:$log_file"

4.6 综合实操案例:电商店铺月度经营报表自动化处理脚本

业务场景:每个月初,运营会发来10个店铺上个月的销售数据压缩包(命名格式:shop_01_202511_data.tar.gz),我需要完成一系列操作,手动处理需要1-2小时,写成脚本后,一键执行即可完成,具体需求:

  1. 解压每个店铺的数据包,提取订单明细文件;

  2. 检查文件是否完整(有没有缺失店铺的数据包);

  3. 提取金额大于100元的高价值订单(运营重点关注);

  4. 按店铺分类存放处理后的文件,方便运营查看;

  5. 设置正确的权限(符合数据合规要求);

  6. 备份原始压缩包,避免数据丢失,符合数据留存要求。

完整脚本代码(可直接复制使用,修改配置区域即可适配自己公司的路径):

#!/bin/bash
# 电商店铺月度报表自动化处理脚本
# 作者:电商数据分析师
# 用途:批量处理店铺月度销售数据,减少手动操作
# 适用场景:店铺数据包命名格式:shop_01_202511_data.tar.gz(shop_店铺编号_年月_data.tar.gz)

# ==================== 配置区域(新手只需要修改这里) ====================
source_dir="/data/from_operation/monthly/"  # 运营上传数据包的目录
target_dir="/data/analysis/monthly/"        # 处理后数据的存放目录
backup_dir="/data/backup/monthly/"          # 原始数据包的备份目录
log_file="/data/logs/monthly_process_$(date +%Y%m%d).log"  # 脚本执行日志
report_date="202511"  # 处理的月份(格式:YYYYMM,比如202511表示2025年11月)

# ==================== 函数定义(封装常用操作,不用修改) ====================
# 日志记录函数(带时间戳,方便追溯)
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $log_file
}

# 检查目录是否存在,不存在则创建(避免目录缺失导致脚本报错)
check_and_create_dir() {
    if [ ! -d "$1" ]; then
        mkdir -p "$1"
        log_message "创建目录:$1"
    fi
}

# ==================== 主流程(核心操作,按顺序执行) ====================
# 写入脚本开始日志
log_message "========== 开始处理 $report_date 店铺月度报表 =========="

# 1. 创建必要的目录(目标目录、备份目录)
check_and_create_dir "$target_dir"
check_and_create_dir "$backup_dir"

# 2. 检查源目录是否有店铺数据包(避免运营未上传数据,脚本白执行)
cd $source_dir
# 查看源目录下是否有符合格式的压缩包,2>/dev/null 避免目录不存在时的报错
if [ -z "$(ls -A *.tar.gz 2>/dev/null)" ]; then
    log_message "错误:源目录 $source_dir 没有找到店铺数据包"
    echo "错误:请先让运营上传店铺数据包到 $source_dir"
    exit 1  # 退出脚本,不再执行后续操作
fi

# 3. 循环处理每个店铺的数据包
for package in *.tar.gz; do
    # 从文件名中提取店铺编号(文件名格式:shop_01_202511_data.tar.gz,用_分割,取第2个字段)
    shop_code=$(echo $package | cut -d'_' -f2)
    log_message "开始处理店铺:$shop_code(数据包:$package)"
    
    # 创建该店铺的专属目录,用于存放处理后的数据
    shop_dir="${target_dir}shop_${shop_code}/"
    check_and_create_dir "$shop_dir"
    
    # 解压数据包到店铺专属目录(-xzf:解压tar.gz格式,-C:指定解压目录)
    log_message "开始解压数据包:$package"
    tar -xzf "$package" -C "$shop_dir"
    
    # 检查解压是否成功($? 是上一条命令的执行结果,0表示成功,非0表示失败)
    if [ $? -eq 0 ]; then
        log_message "解压成功:店铺 $shop_code 的数据包 $package"
    else
        log_message "解压失败:店铺 $shop_code 的数据包 $package(可能是压缩包损坏)"
        continue  # 跳过当前店铺,继续处理下一个
    fi
    
    # 4. 提取高价值订单(金额大于100元)
    # 假设解压后,订单文件名为 order_detail.csv,格式:order_id|user_id|amount|date(用|分隔)
    order_file="${shop_dir}order_detail.csv"
    high_value_file="${shop_dir}high_value_orders.csv"  # 高价值订单输出文件
    
    # 检查订单文件是否存在(避免解压后文件缺失)
    if [ -f "$order_file" ]; then
        # 筛选金额大于100的订单:NR==1 保留表头,$3>100 筛选第3列(金额)大于100的行
        awk -F'|' 'NR==1 || $3>100' "$order_file" > "$high_value_file"
        # 统计高价值订单的条数,方便运营查看
        line_count=$(wc -l < "$high_value_file")
        log_message "店铺 $shop_code:高价值订单共 $line_count 条(金额>100元)"
    else
        log_message "警告:店铺 $shop_code 解压后缺少订单文件(order_detail.csv)"
    fi
    
    # 5. 设置权限(符合数据合规要求:所有者读写,组只读,其他人无权限)
    chmod -R 750 "$shop_dir"
    log_message "权限设置完成:店铺 $shop_code 的目录权限为 750"
    
    # 6. 备份原始数据包(避免数据丢失,符合数据留存要求)
    cp "$package" "$backup_dir"
    log_message "原始数据包备份完成:$package -> $backup_dir"
    
    # 打印当前店铺处理完成的提示(终端可见,方便实时查看进度)
    echo "店铺 $shop_code 处理完成"
done

# 7. 生成处理汇总报告,写入日志
total_shops=$(ls -1 *.tar.gz | wc -l)  # 统计处理的店铺总数
log_message "========== $report_date 店铺月度报表处理完成 =========="
log_message "共处理店铺数:$total_shops 个"
log_message "处理后数据存放目录:$target_dir"
log_message "原始数据包备份目录:$backup_dir"
log_message "脚本执行日志:$log_file"

# 终端输出汇总信息,方便用户快速了解结果
echo "=================================================="
echo "$report_date 店铺月度报表处理完成!"
echo "共处理店铺数:$total_shops 个"
echo "处理后数据:$target_dir"
echo "原始备份:$backup_dir"
echo "详细日志:$log_file"
echo "=================================================="

分步执行说明(新手按步骤来,不会出错):

步骤 操作 预期结果
1 将上面的脚本复制,保存为monthly_process.sh,放在/data/scripts/目录下 脚本文件创建成功,路径:/data/scripts/monthly_process.sh
2 修改脚本“配置区域”的4个路径,适配自己公司的服务器路径 路径修改正确,无拼写错误
3 给脚本添加执行权限:chmod +x /data/scripts/monthly_process.sh 脚本权限变为-rwxr-xr-x,有执行权限
4 让运营将店铺数据包(shop_01_202511_data.tar.gz等)放入source_dir目录 源目录下有10个店铺的压缩包,命名格式正确
5 运行脚本:/data/scripts/monthly_process.sh 脚本开始执行,终端实时输出每个店铺的处理进度
6 查看target_dir目录 每个店铺有独立目录,目录下有原始订单文件和高价值订单文件
7 查看日志文件(log_file路径) 记录每一步操作的时间、结果,无报错信息
提示:脚本可以设置定时任务(第3章讲的crontab),每个月初自动执行,不用手动触发,彻底解放双手。

4.7 本章踩坑清单与合规提示

4.7.1 脚本编写踩坑(新手高频)

场景 错误操作 正确做法
变量赋值 $data_path = "/data"(加了$、空格) data_path="/data"(等号两边无空格,不加$)
变量引用 cp $file_path(文件名带空格时,会报错) cp "$file_path"(加双引号,避免空格问题)
路径切换 脚本里用cd /tmp切换路径后,后续命令依赖当前路径,忘记切回 用子shell执行:(cd /tmp && ls -l),不影响脚本整体路径;或执行完切回原路径
脚本运行 脚本没加执行权限,直接用./script.sh运行 chmod +x script.sh添加权限,或用bash script.sh运行
脚本调试 脚本报错,不知道问题出在哪,反复修改测试 bash -x script.sh逐行调试,查看每一步执行过程和变量值

4.7.2 定时任务踩坑(脚本自动化必看)

很多新手写好脚本后,设置定时任务(crontab),但定时任务不执行,大概率是以下问题:

场景 错误操作 正确做法
路径问题 脚本里用相对路径(比如cp orders/*.csv analysis/),定时任务执行时路径不对 脚本里所有路径必须用绝对路径(比如cp /data/orders/*.csv /data/analysis/
环境变量 脚本依赖PATH环境变量(比如awktar命令),定时任务没有加载环境变量 脚本开头添加source /etc/profile,或写命令的绝对路径(比如/usr/bin/awk
日志问题 定时任务不输出日志,脚本执行失败不知道原因 定时任务中重定向输出到日志:/data/scripts/script.sh >> /data/logs/script.log 2>&1

4.7.3 电商数据合规提示

Shell脚本处理的大多是电商敏感数据(订单、用户信息),必须符合《个人信息保护法》,脚本中要注意以下4点合规要点,避免踩红线:

  • 操作留痕:脚本中所有数据操作(复制、移动、删除、解压)都要写入带时间戳的日志,方便合规审计时追溯“谁、在什么时间、操作了哪些数据”。

  • 权限自动设置:脚本处理完数据后,自动用chmod设置最小权限(比如750目录、640文件),避免人为遗漏,确保无关人员无法访问敏感数据。

  • 敏感字段处理:如果脚本涉及用户数据(比如手机号、收货地址),处理过程中注意脱敏(比如隐藏手机号中间4位),不要在日志里打印完整的敏感信息。

  • 备份保留:原始数据包、处理后的结果数据,要归档备份,保留至少3个月,符合电商数据留存要求,避免数据丢失无法追溯。

脚本示例中的合规设计(可直接借鉴):

  • 每一步操作都写入带时间戳的日志,清晰记录操作过程;

  • 处理完成后,自动给店铺目录设置750权限,符合最小必要原则;

  • 原始数据包先备份再处理,备份目录单独存放,保留原始数据;

  • 日志中不打印任何敏感信息,只记录操作动作和结果。

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐