【问题标题】:If I have a Python script I started in PHP from a web server, how do I stop it?如果我有一个从 Web 服务器用 PHP 启动的 Python 脚本,我该如何停止它?
【发布时间】:2020-04-26 02:08:31
【问题描述】:

我的 RaspberryPi 4 上有一个 Apache Web 服务器,上面有一个用 Python 编写的程序,可以打开一个 8x8 矩阵的红色 LED。我在 Web 服务器上有一个 HTML 和 PHP 页面,因此我可以远程执行该脚本。 HTML 只是 2 个按钮,按一下按钮就会转到这个 PHP 程序:

<?php

  ini_set('display_errors', 1);
  ini_set('display_startup_errors', 1);
  error_reporting(E_ALL);

  if ($_SERVER['REQUEST_METHOD'] == "POST" and isset($_POST['on']))
  {
    lightOn();
  } elseif ($_SERVER['REQUEST_METHOD'] == "POST" and isset($_POST['off']))
  {
    lightOff();
  }

  function lightOn()
  {
    $command = escapeshellcmd('sudo python3 led_display.py');
    $output = shell_exec($command);

    header('Location: index.html');
    exit;

  }

  function lightOff()
  {
    $command = escapeshellcmd('');
    $output = shell_exec($command);

    header('Location: index.html');
    exit;
  }

?>

这个 PHP 程序只识别 2 个按钮中的哪一个被按下并在按下时执行一个函数。对于 lightOn() 函数,它很简单,因为我只执行驱动 8x8 LED 矩阵的脚本。但是我希望用户能够通过按下另一个按钮随时停止脚本。在普通的命令行界面上,我会键入“Control + c”来停止任何正在运行的脚本。我将如何通过 shell_exec 或任何其他方法在 PHP 中实现这一点?

【问题讨论】:

  • 你的代码不是很漂亮,所以:你为什么有这些函数lightOn e lightOff?这些功能是否在其他地方使用?这两个函数中有不必要的重复代码
  • 能够sudo 从某些网络请求触发听起来像是灾难的秘诀。
  • @OlafKock 在不使用 sudo 的情况下实现我想要做的事情的正确方法是什么?

标签: php linux apache raspberry-pi


【解决方案1】:

在您的服务器中,通过pstop 甚至htop 命令找出进程ID (PID) 是什么。比你可以用命令kill {pid_number}杀死它。

类似:

$ ps aux | grep led_display # the first number that appears is the PID. let's assume it's 1234
$ kill 1234

【讨论】:

  • 我尝试了这种方法,找到了 pid 并将 'kill {pid}' 和 'sudo kill {pid}' 作为命令,但是当我单击按钮时,灯不会熄灭。我认为,问题在于,如果您在 linux 中运行 python 脚本时考虑到这一点,则用户无法在运行时发出命令。我需要一种方法来在脚本运行时模拟 Control + C 以在现场停止它。谢谢你的回答。
【解决方案2】:

假设您可以控制sudoers 文件并知道如何制作它,以便您的网络服务器进程可以在没有密码的情况下执行lightOff 中引用的命令,您应该可以这样做

$command = escapeshellcmd('sudo pkill -TERM led_display.py');

当然,这会终止任何名为 led_display.py 的进程,而不仅仅是您从 Web 服务器进程启动的那个。

编辑:

如果你在后台处理进程会发生什么?

$command = escapeshellcmd('sudo python3 led_display.py > /dev/null 2>&1 &');

【讨论】:

  • 我试过这个和上面的答案。两者都不起作用,但我认为问题与另一个问题相同。当 python 脚本在 linux 中运行时,用户无法键入。由于 shell_exec 本质上就像输入一个命令,所以我在lightsOff() 函数中输入的任何内容在脚本完成之前都不会被执行。我需要一些模拟“Control + C”的东西,即使用户无法键入命令,它也会当场停止脚本。不管怎样,谢谢你的回答。
  • 如果你在后台处理进程会发生什么?请参阅上面的编辑。
  • 对不起,我脑子有问题……你不是要为杀戮尝试做背景,而是 led_dispaly 的开始。请再检查一次。
  • led_display 真的有后台吗?也就是说,如果您尝试在 `lightOn();` 之后打印任何内容 - 会打印吗?
  • 不,我不相信它会成为背景。它只是主动运行,然后执行下一行代码。我将如何让它在后台运行?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 2013-09-21
  • 1970-01-01
  • 2018-01-09
  • 1970-01-01
相关资源
最近更新 更多