Quantcast
Channel: 小蓝博客
Viewing all articles
Browse latest Browse all 3145

在sh脚本中执行PHP并捕获异常

$
0
0

sh 脚本中执行 PHP 并捕获异常

在编写 Shell 脚本时,有时需要执行 PHP 脚本并捕获其中的异常或错误。为了实现这一目标,我们需要确保 PHP 脚本执行过程中产生的异常或错误可以反馈给 Shell 脚本,并根据这些错误执行不同的操作。

一、问题分析

sh 脚本中执行 PHP 脚本的基本步骤通常如下:

  1. 调用 PHP 脚本。
  2. 捕获 PHP 脚本的输出和错误。
  3. 根据 PHP 脚本的退出码判断是否发生异常或错误。
  4. 执行相应的错误处理逻辑。

二、捕获 PHP 异常的方法

在 PHP 中,异常或错误会影响脚本的退出状态。通过检查 PHP 的返回码,我们可以确定是否发生了错误。此外,还可以将 PHP 脚本的标准输出和错误输出分别重定向到不同的文件或变量中,以进一步处理。

1. 使用 PHP 的 try-catch 结构

在 PHP 脚本中,使用 try-catch 块来捕获异常并返回非零的退出码,便于在 Shell 脚本中检测。

示例 PHP 脚本 script.php

<?php
try {
    // 可能抛出异常的代码
    throw new Exception("Something went wrong!");
} catch (Exception $e) {
    // 输出错误消息
    fwrite(STDERR, $e->getMessage() . "\n");
    exit(1); // 返回非零值表示异常
}

解释:

  • try-catch:捕获异常,确保异常不会导致 PHP 脚本崩溃,而是输出错误消息到标准错误流(STDERR),并返回退出状态码 1

2. 在 sh 脚本中捕获异常

Shell 脚本可以通过 $? 获取上一个命令的退出状态码。0 表示成功,非零表示错误。我们可以根据这个状态码来判断 PHP 脚本是否执行成功。

示例 sh 脚本 run_php.sh

#!/bin/sh

# 执行 PHP 脚本,并将输出和错误分别重定向到不同的文件
php script.php > output.log 2> error.log
EXIT_CODE=$?

# 检查 PHP 脚本的退出码
if [ $EXIT_CODE -ne 0 ]; then
    echo "PHP 脚本执行出错,错误信息如下:"
    cat error.log  # 输出错误日志
else
    echo "PHP 脚本执行成功,输出如下:"
    cat output.log  # 输出正常日志
fi

# 清理日志文件
rm -f output.log error.log

解释:

  • php script.php > output.log 2> error.log:将 PHP 脚本的标准输出重定向到 output.log 文件,错误输出重定向到 error.log 文件。
  • $?:捕获 PHP 脚本的退出状态码,并存储在变量 EXIT_CODE 中。
  • if [ $EXIT_CODE -ne 0 ]:判断退出码是否非零,非零表示执行出错。
  • cat error.logcat output.log:分别输出错误日志和正常日志内容。
  • 清理日志文件:脚本结束时删除生成的日志文件,确保不留下临时文件。

三、使用 set -e 强化错误处理

为了确保 Shell 脚本在发生任何错误时立即停止执行,可以使用 set -e 命令。set -e 命令会让脚本在遇到任何返回非零状态的命令时立即退出。

示例 sh 脚本:

#!/bin/sh
set -e  # 开启遇错即停模式

# 尝试执行 PHP 脚本
php script.php > output.log 2> error.log

# 如果 PHP 脚本执行成功,输出日志
echo "PHP 脚本执行成功,输出如下:"
cat output.log

# 清理日志文件
rm -f output.log error.log

解释:

  • set -e:开启错误处理,遇到任何命令返回非零状态时立即退出脚本。
  • 如果 PHP 脚本执行失败,Shell 脚本会立即退出,而不会执行后续的日志输出和清理操作。

四、示例场景扩展

1. 捕获并处理不同类型的错误

有时我们需要根据错误类型进行不同的处理。可以在 PHP 中通过不同的异常处理逻辑返回不同的退出码,在 Shell 脚本中根据退出码执行不同的处理。

示例 PHP 脚本:

<?php
try {
    // 模拟不同的错误情况
    if (rand(0, 1)) {
        throw new Exception("General error");
    } else {
        throw new RuntimeException("Runtime error");
    }
} catch (RuntimeException $e) {
    fwrite(STDERR, $e->getMessage() . "\n");
    exit(2);  // 返回不同的状态码
} catch (Exception $e) {
    fwrite(STDERR, $e->getMessage() . "\n");
    exit(1);
}

sh 脚本中,根据不同的退出码进行不同的处理:

#!/bin/sh

php script.php > output.log 2> error.log
EXIT_CODE=$?

case $EXIT_CODE in
    1)
        echo "通用错误发生,错误信息如下:"
        ;;
    2)
        echo "运行时错误发生,错误信息如下:"
        ;;
    *)
        echo "未知错误,退出码:$EXIT_CODE"
        ;;
esac

cat error.log
rm -f output.log error.log

五、总结

通过在 sh 脚本中调用 PHP 脚本,并捕获其异常和错误,可以更灵活地控制脚本的执行流程。在实际应用中,这种方式可以有效提升自动化脚本的健壮性和可维护性。无论是处理单一错误还是根据不同错误进行不同处理,使用 Shell 脚本结合 PHP 的 try-catch 机制,可以实现更复杂的错误处理逻辑。

步骤解释
编写 PHP 脚本使用 try-catch 机制捕获异常并返回不同的退出码
执行 PHP 脚本在 Shell 脚本中使用 php 命令执行 PHP 脚本,并捕获输出和错误
捕获 PHP 脚本的退出状态码通过 $? 捕获退出状态码,判断是否发生错误
根据错误类型处理使用 caseif 判断不同的退出码,执行相应的错误处理逻辑

Viewing all articles
Browse latest Browse all 3145

Trending Articles