草庐IT

php - 在 CLI 上的脚本中止后执行代码

coder 2024-04-14 原文

在我的脚本在 PHP 中中止后,我尝试执行一些最终代码。假设我有这个 PHP 脚本:

while(true) {
    echo 'loop';
    sleep(1);
}

如果我使用 $ php script.php 执行脚本,它会一直运行到给定的执行时间。

现在我喜欢在脚本中止后执行一些最终代码。所以如果我

  • 点击 Ctrl+C
  • 执行时间结束

在这些情况下甚至有可能进行一些清理吗?

我用 pcntl_signal 试过了但没有运气。还有 register_shutdown_function但这只有在脚本成功结束时才会被调用。

更新

我发现(thx to rch's link)我可以通过以下方式“捕捉”事件:

pcntl_signal(SIGTERM, $restartMyself); // kill
pcntl_signal(SIGHUP,  $restartMyself); // kill -s HUP or kill -1
pcntl_signal(SIGINT,  $restartMyself); // Ctrl-C

但是如果我扩展我的代码

$cleanUp = function() {
    echo 'clean up';
    exit;
};

pcntl_signal(SIGINT, $cleanUp);

如果我按 Ctrl+C,脚本会继续执行,但不会遵守 $cleanUp 闭包中的代码。

最佳答案

函数pcntl_signal()是脚本被使用 Ctrl-C(和其他信号)中断的情况的答案。您必须注意文档。它说:

You must use the declare() statement to specify the locations in your program where callbacks are allowed to occur for the signal handler to function properly.

除其他事项外,declare() 语句安装了一个回调函数,该函数通过调用函数 pcntl_signal_dispatch() 来处理自上次调用以来接收到的信号的调度。依次调用您安装的信号处理程序。

或者,您可以调用函数 pcntl_signal_dispatch()当你认为它适合你的代码流时,你自己(并且根本不要使用 declare(ticks=1))。

这是一个使用declare(ticks=1)的示例程序:

declare(ticks=1);

// Install the signal handlers
pcntl_signal(SIGHUP,  'handleSigHup');
pcntl_signal(SIGINT,  'handleSigInt');
pcntl_signal(SIGTERM, 'handleSigTerm');


while(true) {
    echo 'loop';
    sleep(1);
}

// Reset the signal handlers
pcntl_signal(SIGHUP,  SIG_DFL);
pcntl_signal(SIGINT,  SIG_DFL);
pcntl_signal(SIGTERM, SIG_DFL);



/**
 * SIGHUP: the controlling pseudo or virtual terminal has been closed
 */
function handleSigHup()
{
    echo("Caught SIGHUP, terminating.\n");
    exit(1);
}

/**
 * SIGINT: the user wishes to interrupt the process; this is typically initiated by pressing Control-C
 *
 * It should be noted that SIGINT is nearly identical to SIGTERM.
 */
function handleSigInt()
{
    echo("Caught SIGINT, terminating.\n");
    exit(1);
}

/**
 * SIGTERM: request process termination
 *
 * The SIGTERM signal is a generic signal used to cause program termination.
 * It is the normal way to politely ask a program to terminate.
 * The shell command kill generates SIGTERM by default.
 */
function handleSigTerm()
{
    echo("Caught SIGTERM, terminating.\n");
    exit(1);
}

关于php - 在 CLI 上的脚本中止后执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30932746/

有关php - 在 CLI 上的脚本中止后执行代码的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  4. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  5. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  6. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  7. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  8. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  9. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  10. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

随机推荐