我需要在任何时候执行一个 PHP 文件httpd服务启动或重新启动。我发现Systemd有一个名为**的配置设置执行启动后,这看起来非常适合我需要做的事情。
我更新了该/etc/systemd/system/multi-user.target.wants/httpd.service
文件以反映以下内容:
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecStartPost=/bin/php /usr/sbin/php_test
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi-user.target
内容为/usr/sbin/php_test是:
#!/bin/php
<?php
echo "Writing to /tmp/php-test.txt...\n";
$myfile = fopen("/tmp/php-test.txt", "w") or die("Unable to open file!");
$txt = "TEST! " . date("F j, Y, g:i a") . PHP_EOL;
fwrite($myfile, $txt);
fclose($myfile);
echo "Done!!\n";
?>
然后我 chmod 777 php 文件并通过systemctl daemon-reload
.但是当我重新启动 httpd 时,它不会创建我期望看到的 /tmp/php-test.txt 文件。
如果我/bin/php /usr/sbin/php_test
通过命令行执行,它工作得很好。
我找到了一个单独的StackOverflow线程说明 Systemd.service
从下到上读取文件,所以我将该ExecStartPost
行移动到该行的正上方ExecStart
,重新加载守护程序文件并再次重新启动 apache,但没有成功......
我在这里做错了什么?
谢谢!
更新1
我将httpd.service
文件更改为以下内容:
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecStartPost=/bin/bash -c "/bin/php -f /tmp/php_test"
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi-user.target
现在我收到一个错误(至少是某物继续!)。当我通过 查看日志时journalctl -xe
,我看到以下内容:
Apr 19 12:47:46 silo-stg-a01.cymedica.com systemd[1]: Starting The Apache HTTP Server...
-- Subject: Unit httpd.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit httpd.service has begun starting up.
Apr 19 12:47:46 silo-stg-a01.cymedica.com bash[13268]: Could not open input file: /tmp/php_test
Apr 19 12:47:46 silo-stg-a01.cymedica.com systemd[1]: httpd.service: control process exited, code=exited status=1
Apr 19 12:47:47 silo-stg-a01.cymedica.com systemd[1]: Failed to start The Apache HTTP Server.
-- Subject: Unit httpd.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit httpd.service has failed.
--
-- The result is failed.
Apr 19 12:47:47 silo-stg-a01.cymedica.com systemd[1]: Unit httpd.service entered failed state.
Apr 19 12:47:47 silo-stg-a01.cymedica.com systemd[1]: httpd.service failed.
错误是无法打开输入文件:/tmp/php_test.. 还不确定这意味着什么。
我知道,即使 PHP 文件无法执行,在命令前加上连字符也会让进程继续进行,但这不是我想要解决的问题。我需要 PHP 脚本才能正确执行。
供参考,如果你想知道为什么我让它执行 /bin/bash -c "/bin/php -f /tmp/php_test"
不仅仅是 /bin/php -f /tmp/php_test
我只是尝试让它从 bash 命令执行 php 脚本。但如果我将其更改为 just /bin/php -f /tmp/php_test
,我会得到完全相同的错误journalctl
更新2
我注意到,如果我ExecStartPost
用 PHP 命令替换该行:
ExecStartPost=/bin/logger "ExecStartPost 1"
(就在该ExecStart
行之后),它记录执行开始后 1到日志就好了...所以我认为它与 php 文件本身的执行方式有关
答案1
您的单位文件中有:
PrivateTmp=true
这意味着 systemd 将为单元/tmp
和/var/tmp
目录创建一个单独的命名空间。删除线即可使用通常的/tmp
.