![如何在 Asterisk 上以 root 身份启动期间运行 PowerShell 文件?](https://linux22.com/image/190252/%E5%A6%82%E4%BD%95%E5%9C%A8%20Asterisk%20%E4%B8%8A%E4%BB%A5%20root%20%E8%BA%AB%E4%BB%BD%E5%90%AF%E5%8A%A8%E6%9C%9F%E9%97%B4%E8%BF%90%E8%A1%8C%20PowerShell%20%E6%96%87%E4%BB%B6%EF%BC%9F.png)
在 Asterisk 启动/重新启动时,我想要执行 PowerShell 文件。
我创建了一个.ps1文件/var/spool/
,应在其上从星号目录复制新文件并将其传输到 Azure 存储容器。该文件应该获取每个最后的录制文件并将其传输到 Azure 的容器。当我在 root 上手动运行该命令时,它起作用了。这是成功上传到 Azure 容器的记录文件的输出。
Name BlobType Length ContentType L
a
s
t
M
o
d
i
f
i
e
d
---- -------- ------ ----------- -
out-067…9249.0.wav BlockBlob 44 application/octet-stream 2
uploaded!
为了获得每一个新的录音,它必须无限地运行(每分钟检查一次新文件)。为此,我使用了循环 do/while($true),sleep 60
其中包含一个命令。如果系统重新启动或断电,我希望此文件(ps1)在操作系统启动后再次开始运行。
为此,我尝试添加pwsh /var/spool/transferrecordings.ps1
命令/etc/rc.local使其在系统重新启动时工作。我编辑了这个目录,vi /etc/rc.local
如下所示:
这是我在目录中使用的脚本/etc/rc.local
。
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
pwsh /var/spool/transferrecordings.ps1
exit 0
但服务器启动时似乎没有发生任何事情。
我尝试crontab -e
通过添加命令来编辑 crontab:
@reboot pwsh /var/spool/transferrecordings.ps1
。又什么都没有了。
我正在使用 Sangoma Linux (CentOS 3.10.0)。
请问有什么建议吗?
答案1
(我写这篇文章的方式是希望遇到这个答案的其他用户可以使用它,而不仅仅是OP。)
解决此类问题有多种方法,以及每种方法的问题和权衡。通常,您不希望某个进程持续运行而耗尽您所有的 CPU/RAM,否则您将无法使用系统!
您可以将代码编写为守护进程,它将“永远”循环,但在循环迭代之间它将进入空闲/不活动/睡眠状态,以便其他进程/程序也得到服务。在守护进程模式下有很多事情需要注意,例如并发、竞争条件、死锁、意外退出时的处理重新启动,甚至确保不会多次运行同一个守护进程,除非您有意这样做并了解如何安全地做。我不会在这里进一步详细介绍这一点——在网上搜索“编写守护进程”。
另一种方法是使用由系统事件(例如新文件创建、修改、访问等)触发的各种系统监视工具。此方法也存在一些问题,如果您不了解如何安全使用它,可能会导致系统崩溃。同样,我不会在这里进一步详细介绍他的方法。如果您认为这种方法最适合您,请搜索“文件系统事件通知”。
还有另一种方法(还有更多方法)是使用cron
大多数(所有?)un*x 系统通用的守护进程,定期运行命令或更可能是 shell 脚本,例如每分钟运行一次。这种方法也有缺陷,但通常更容易采取措施来避免。需要调整的最大问题通常是您的 shell 脚本(或 powershell,或 perl/pythen/其他命令/脚本)应该设计为处理只有一次每次都执行,而不是无限循环。让cron
我们一次又一次地重复执行它(cron
它本身被精心设计为作为守护进程运行,并处理作为守护进程的所有细节和许多问题,因此您不必这样做。)一旦处理完成,就可以它会尽快退出,以便系统和您可以回去做其他事情,例如玩您最喜欢的游戏。 ;-)
通常,您需要注意的“cron jobs”的最大问题是:
1:将间隔设置得足够远以避免重叠,并避免在命令/脚本内重复循环(尤其是无限循环!)。否则,即使前一个进程仍在循环,cron 也会启动一个新进程。不久之后,您将有数百或数千个相同的脚本运行、循环并相互冲突,从而耗尽 CPU、RAM 等。
2:与上一个相关,您希望脚本执行以下操作:并完成-- 在触发票据再次运行之前,它需要尽快执行什么操作cron
,如上所述。如果两次迭代有可能会重叠(例如,在通过网络复制大文件时可能会发生这种情况),您需要计划潜在的并发问题、死锁等。(许多脚本通过跟踪最新的版本来处理此问题) *.pid 文件中的 PID(进程 ID),用于检测前一个迭代是否仍在进行中,如果前一个迭代仍在执行,则中止“新”执行。)
3:与这种情况相关的是,您需要确保如果脚本的多个进程被触发,则只有其中一个进程执行复制操作。否则,它们会与尝试复制完全相同的文件/数据发生冲突。 (这就是为什么 *.pid 方法用于在检测到先前的执行尚未完成时中止。我将如何执行所有这些操作的详细信息留给读者作为练习......练习他们的搜索和研究技能...)
4:您可能需要考虑的最后一个问题是用户访问权限和许可。该cron
工具以不同的模式运行——一种是系统模式,其中需要告知“crontab”配置以哪个用户帐户执行命令/脚本,因此那用户帐户的权限;另一种模式是每用户模式,其中cron
已经知道要执行命令/脚本的用户帐户,因为它已经隐含了。 (请注意,cron
确实不是 执行用户~/.bashrc
或任何内容,因此如果需要,您需要将其包含在命令/脚本中。)
在某些情况下还需要注意其他问题,因此请务必了解这些问题以及发生这些问题时如何处理。网上已经有很多资料了cron
,这里就不再重复了。去网上搜索一下吧。
作为OP的最后一点,我强烈建议您rsync
如果可以的话学习使用该命令。它有很多选项来控制复制方式/内容、检测文件是否已存在、检测一个文件是否比另一个文件旧/新,以及您可能会发现有用的更多功能。