Linux 6.1. PHP 8.2.7. KDE Plasma 5.x. X11.

长期以来,我的PHP CLI脚本一直有一个非常烦人的问题,这个问题不断出现并导致问题.现在我终于做了一个最小的测试用例,希望这个问题能一劳永逸地解决.

如果你做了这三件事:

  1. SIGHUP信号注册一个处理程序函数(它是空的/不做任何事情).
  2. 判断来自用户的输入(fgets(STDIN);)...
  3. xterm -e php test.php一样运行PHP CLI脚本(这是我必须调用它的方式,因为复杂的原因与这个问题无关).

...然后the resulting XTerm terminal emulator window will not be possible to close by clicking the "X" in the top-right corner!如果你点击它,什么都不会发生.

只要您注释或删除注册信号处理程序的行,它将允许您在如上所述运行时关闭窗口.

Test case

  • xterm -e php 1.php =单击"X"CANNOT以关闭Xerm窗口.
  • xterm -e php 2.php =单击"X"CAN以关闭Xerm窗口.

1.php:

<?php
    
    function dummy_handler() { /* deliberately left empty */ }
    pcntl_signal(SIGHUP, 'dummy_handler');
    $input = fgets(STDIN);

2.php:

<?php

    function dummy_handler() { /* deliberately left empty */ }
    $input = fgets(STDIN);

我能做些什么来绕过这个?为了明确起见,我需要注册处理程序函数,我需要用-e调用xterm,我需要"等待输入".我还应该指出的是,我已经try 了那些classic 的setsidnohup Linux技巧,但没有任何运气.我不明白到底是什么导致的.

请不要告诉我"只要记住使用Ctrl + C"之类的东西;我需要能够在某些PHP CLI脚本的自然生命结束之前关闭它们,通过点击"X",我需要能够在它关闭之前调用一些清理 routine .(在这个最小的例子中,处理程序函数是空的,只是为了证明在没有我做任何奇怪/复杂的事情的情况下,它仍然会发生.

不管桌面环境和终端模拟器如何,它都可能发生,但我在Linux上使用KDE Plasma和Xterm,这就是我需要的.

更新:在处理程序函数中使用exit(1);不会有什么不同.

推荐答案

您可以通过将命令包装在shell命令中来解决这个问题:

xterm -e sh -c "php 1.php"

你可以看到使用strace的行为(例如,"strace—fo trace.log—s 1024 xterm"等):

  • 在非工作的情况下,初始xterm进程忽略SIGHUP(xterm创建两个进程,第一个进程管理伪终端,第二个进程管理X窗口). 这个信号被传递给php进程(在脚本中捕获).
  • 在工作情况下,即使初始的xterm进程忽略了SIGHUP,信号也会传递给shell进程,shell进程不会忽略它.

整个日志(log)很长,但只有SIGHUP行(并参考整个日志(log)来确定哪个process—id是哪个)就能说明问题. 以下是非工作 case 的摘录(2209为初始):

2212  rt_sigaction(SIGHUP, {sa_handler=SIG_IGN, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f7719fd0050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
2212  rt_sigaction(SIGHUP, {sa_handler=SIG_DFL, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f7719fd0050},  <unfinished ...>
2209  rt_sigaction(SIGHUP, {sa_handler=SIG_IGN, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f7719fd0050},  <unfinished ...>
2212  rt_sigaction(SIGHUP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
2212  rt_sigaction(SIGHUP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
2212  rt_sigaction(SIGHUP, {sa_handler=0x5567ef0cdeb0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7fb3ba001050}, NULL, 8) = 0
2212  read(3, "<?php\n    \n    function dummy_handler() { /* deliberately left empty */ }\n    pcntl_signal(SIGHUP, 'dummy_handler');\n    $input = fgets(STDIN);\n", 4096) = 144
2212  rt_sigaction(SIGHUP, {sa_handler=0x5567ef0cdeb0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7fb3ba001050}, NULL, 8) = 0
2209  kill(-2212, SIGHUP)               = 0
2212  --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=2209, si_uid=1001} ---
2209  kill(-2212, SIGHUP)               = 0
2212  --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=2209, si_uid=1001} ---
2212  rt_sigaction(SIGHUP, {sa_handler=0x5567ef0cdeb0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_INTERRUPT|SA_SIGINFO, sa_restorer=0x7fb3ba001050}, NULL, 8) = 0
2209  kill(-2212, SIGHUP)               = -1 ESRCH (No such process)

工作 case (2219为初始):

2220  rt_sigaction(SIGHUP, {sa_handler=SIG_IGN, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f6b9ec83050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
2220  rt_sigaction(SIGHUP, {sa_handler=SIG_DFL, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f6b9ec83050},  <unfinished ...>
2219  rt_sigaction(SIGHUP, {sa_handler=SIG_IGN, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f6b9ec83050},  <unfinished ...>
2221  rt_sigaction(SIGHUP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
2221  rt_sigaction(SIGHUP, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
2221  rt_sigaction(SIGHUP, {sa_handler=0x55e3610ddeb0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8e6a25b050}, NULL, 8) = 0
2221  read(3, "<?php\n    \n    function dummy_handler() { /* deliberately left empty */ }\n    pcntl_signal(SIGHUP, 'dummy_handler');\n    $input = fgets(STDIN);\n", 4096) = 144
2221  rt_sigaction(SIGHUP, {sa_handler=0x55e3610ddeb0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f8e6a25b050}, NULL, 8) = 0
2219  kill(-2220, SIGHUP)               = 0
2221  --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=2219, si_uid=1001} ---
2220  --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=2219, si_uid=1001} ---
2220  +++ killed by SIGHUP +++
2219  --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=2220, si_uid=1001, si_status=SIGHUP, si_utime=0, si_stime=0} ---
2221  --- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
2219  kill(-2220, SIGHUP)               = 0
2221  --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=2219, si_uid=1001} ---
2221  rt_sigaction(SIGHUP, {sa_handler=0x55e3610ddeb0, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_INTERRUPT|SA_SIGINFO, sa_restorer=0x7f8e6a25b050}, NULL, 8) = 0

Php相关问答推荐

过滤WooCommerce管理员订单列表(+HPOS)中包含其作者产品的订单

从WC会话变量更改WooCommerce checkout 托运方法成本

筛选器具有多个查询之一

如何在Laravel Model中自定义多个日期属性的日期格式?

fpm-php + nginx + POST数据

在带有livewire 3的laravel中使用规则方法时,无法进行实时验证

在WooCommerce中只允许高价产品的BACS付款

Rappasoft Datatables V2(我想在另一个表具有相同值列时显示数据)

在WooCommercestore 页面上显示库存产品属性的值

Woocommerce单一产品Ajax添加到带有自定义购物车项目数据的购物车

curl_close()未从PHP 8开始写入CURLOPT_COOKIEJAR会话文件

htaccess 配置提供静态文件和动态文件

在php中计算两个没有假期的日期之间的小时差

调用未定义的方法 mysqli::execute_query()

从 Laravel 机制中排除目录并直接访问该目录

防止使用woocommerce_checkout_process下单

PHP Symfony 在测试.env文件中将接口自动装配作为构造函数参数,但使用接口的特定类

Laravel 路由参数中的 ":" 是什么?

如果有很多重定向,PHP curl 的行为不像命令行 curl

PHP 将数组值插入到 csv 列