0Pricing
Linux Server Deployment & SSH Mastery · 课时

脚本中的错误处理与日志记录

实施可靠的错误处理,重定向脚本输出,并生成有意义的日志,以监控脚本执行情况和排查问题。

脚本中的错误处理与日志记录 是 CoddyKit 上的免费 Linux Server Deployment & SSH Mastery 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Linux Server Deployment & SSH Mastery 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Linux Server Deployment & SSH Mastery 课程共包含 4 节课。

让您的脚本更可靠

想象一下,您的脚本正在服务器上运行,执行着重要任务。如果出现问题,会发生什么?

  • 它会不会悄无声息地失败?
  • 它会不会留下难以收拾的残局?
  • 您能否判断它何时以及为何失败?

健壮的脚本能够妥善处理错误,并提供清晰的日志。本课将教您如何做到这一点!

了解退出代码

Linux 中的每个命令和脚本结束时,都会返回一个退出代码(也称退出状态)。这个数字会告诉您操作是成功还是失败。

  • 0:表示成功!一切顺利。
  • 1-255:表示失败。特定数字可能表示错误类型。

让我们看看它的实际效果:

#!/bin/bash
# This script demonstrates exit codes

echo "Attempting a successful command..."
ls /tmp
echo "Exit code for 'ls /tmp': $?"

echo

echo "Attempting a failing command..."
ls /nonexistent_directory
echo "Exit code for 'ls /nonexistent_directory': $?"

检查命令状态

任意命令运行后,您都可以使用特殊变量 $? 检查它的退出代码。这对于在脚本中做出判断非常有用。

您可以使用 if 语句来响应成功或失败:

#!/bin/bash
# Check if a file exists before trying to read it

FILENAME="test_file.txt"
touch $FILENAME # Create it for success case

if [ -f "$FILENAME" ]; then
  echo "File '$FILENAME' exists. Processing..."
  # ... do something with the file ...
  rm $FILENAME # Clean up
else
  echo "Error: File '$FILENAME' not found!"
  exit 1
fi

echo "Script finished."

`set -e`:出错时退出

对于简单脚本而言,到处手动检查 $? 可能很繁琐。命令 set -e 会改变脚本的行为:

  • 如果任何命令以非零状态退出(即失败),脚本会立即终止。
  • 这样可以防止脚本继续使用可能已损坏的数据或处于无效状态。

尝试运行此脚本。如果 cp 命令失败,会发生什么?

#!/bin/bash
set -e

echo "Starting important operations..."
mkdir my_temp_dir
cp /nonexistent_source my_temp_dir/target # This will fail

echo "This line will not be reached if cp fails."
rmdir my_temp_dir
echo "Script finished successfully."

使用 `trap` 执行清理

有时,即使脚本失败,您仍然需要执行清理任务,例如删除临时文件。trap 命令允许您捕获信号(例如退出或错误信号)并运行命令。

  • EXIT:脚本退出时运行,无论成功还是失败。
  • ERR:命令以非零状态退出时运行(前提是 set -e 处于启用状态)。

在这里,我们确保临时目录始终会被删除:

#!/bin/bash

TEMP_DIR="/tmp/my_script_temp_$(date +%s)"

function cleanup {
  echo "Cleaning up temporary directory: $TEMP_DIR"
  rm -rf "$TEMP_DIR"
}

trap cleanup EXIT

mkdir "$TEMP_DIR"
echo "Working in $TEMP_DIR..."
# Simulate some work, maybe it fails
# cp /nonexistent_file "$TEMP_DIR/" # Uncomment to test failure

echo "Script completed."

重定向输出

脚本运行时,通常会打印消息。这些消息主要分为两类:

  • 标准输出(stdout):普通消息(文件描述符 1)。
  • 标准错误(stderr):错误消息(文件描述符 2)。

您可以将这些数据流重定向到文件,而不是显示在屏幕上:

  • command > file:将 stdout 重定向到 file。
  • command 2> file:将 stderr 重定向到 file。

让我们分别保存成功消息和错误消息。

#!/bin/bash
# Redirect stdout to success.log and stderr to error.log

echo "This is a success message." > success.log
ls /nonexistent_path 2> error.log

echo "Check success.log and error.log files."
# To view them after running:
# cat success.log
# cat error.log

将所有输出写入一个文件

很多时候,将标准输出和标准错误都写入同一个日志文件会很有用,这样更便于查看。实现方式有几种:

  • command > file 2>&1:先将 stdout 重定向到 file,再将 stderr 重定向到 stdout 当前指向的位置(即该文件)。
  • command &> file:实现相同功能的更简短、更现代的语法。

这非常适合创建全面记录脚本执行过程的日志。

#!/bin/bash
# Redirect both stdout and stderr to a single log file

LOG_FILE="combined_script.log"

echo "Starting script..." &> "$LOG_FILE"
echo "This message goes to stdout." &>> "$LOG_FILE"
ls /nonexistent_dir 2>&1 | tee -a "$LOG_FILE"
echo "Script finished." &>> "$LOG_FILE"

echo "Check the '$LOG_FILE' file for all output."

为日志添加时间戳

调试时,了解某个事件何时发生至关重要。为日志消息添加时间戳,会让日志更有用。

您可以使用 date 命令,将当前日期和时间添加到每条日志记录的开头。这样有助于按时间顺序追踪事件。

#!/bin/bash

LOG_FILE="timestamped_script.log"

function log_message {
  echo "$(date +%Y-%m-%d_%H:%M:%S) - $1" &>> "$LOG_FILE"
}

log_message "Script started."
sleep 1
log_message "Performing task A..."
# Simulate an error
ls /no_such_place || log_message "Error: Command failed."
sleep 1
log_message "Script finished."

echo "Check '$LOG_FILE' for timestamped entries."

使用 `logger` 发送到系统日志

对于重要事件,您可能希望将消息直接发送到系统的日志记录设施(syslog)。logger 命令正是用于此目的。

  • 系统日志通常由 journalctl 等工具管理(在使用 systemd 的系统上)。
  • 这样可以将脚本的重要消息与其他系统事件集中记录。
  • 这对于记录严重错误或审计轨迹很有用。

使用 logger 发送的消息可以通过 journalctl -f 或 tail -f /var/log/syslog 查找(具体取决于您的系统)。

#!/bin/bash
# Send a message to system logs

SCRIPT_NAME="MyBackupScript"

logger -t "$SCRIPT_NAME" "Starting daily backup operation."

# Simulate a task
sleep 2
if [ $(($RANDOM % 2)) -eq 0 ]; then
  logger -t "$SCRIPT_NAME" -p user.info "Backup successful."
else
  logger -t "$SCRIPT_NAME" -p user.err "Backup failed: Disk full."
fi

echo "Messages sent to system logs. Check with 'journalctl -t $SCRIPT_NAME'."

错误处理检查

您编写了一个用于处理一些文件的 Bash 脚本。您希望脚本在其中任何命令失败时立即退出,同时还希望无论脚本以何种方式退出,临时目录都能被清理。

要实现这两个目标,您主要会使用哪两个 Bash 命令?

回顾与后续步骤

您已经学会了如何让 Bash 脚本更加健壮,也更易于调试!

  • 退出代码:了解命令是成功还是失败。
  • set -e:出错时自动退出。
  • trap:脚本退出时执行清理操作。
  • 输出重定向:控制 stdout 和 stderr 的去向。
  • 时间戳:为日志添加上下文信息。
  • logger:接入系统范围的日志记录功能。

应用这些技术后,您的自动化任务将更加可靠且易于管理。继续练习,构建真正经久稳定的自动化流程!

常见问题解答

「脚本中的错误处理与日志记录」课时是免费的吗?

是的 — 「脚本中的错误处理与日志记录」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Linux Server Deployment & SSH Mastery 课程的其余内容,请升级到 CoddyKit PRO。 Linux Server Deployment & SSH Mastery 课程共包含 4 节课。

「脚本中的错误处理与日志记录」这节课中我会学到什么?

实施可靠的错误处理,重定向脚本输出,并生成有意义的日志,以监控脚本执行情况和排查问题。 你通过在浏览器中直接运行的动手代码来练习 Linux Server Deployment & SSH Mastery,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Linux Server Deployment & SSH Mastery 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Linux Server Deployment & SSH Mastery 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「脚本中的错误处理与日志记录」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Linux Server Deployment & SSH Mastery 课中编写并运行代码吗?

能。每节 Linux Server Deployment & SSH Mastery 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Bash 脚本入门
  2. 自动化服务器任务
  3. 脚本中的错误处理与日志记录
  4. 函数、参数与可复用脚本
← 返回 Linux Server Deployment & SSH Mastery