linux下的进程信号(posix signal),对powershell无用论

powershell传教士 原创文章 2023-11-02 允许转载,但必须保留名字和出处。

---【前言】---

话说某日,我喊出了“给出一个bash比powershell好的特色,我就给你1块钱活动”。

当然是都用最新版对比。从语法和库方面对比主流特色。必须是优点,糟粕我不给钱。

某位群友来喊道“bash的trap可以处理linux进程信号,powershell不行”的结论。

并给出了网址: https://segmentfault.com/a/1190000022092541

这个话题很好。

而我的观点是: posix-signal对powershell无用论

下面就让我们来谈一谈。

---【正文】---

这些信号(posix-signal),主要由管理员(或其他进程)发送,由进程自身接收并处理。

发送这些信号,可以用kill,如:

kill -s HUP 进程pid

这里我们主要谈【对比bash,linux版powershell进程,接收并处理这些信号】。

首先让我们看看有哪些

信号名,信号用途。

SIGHUP,对于守护进程,用于重新读取配置文件。对于正常进程,用于脱离终端。

SIGINT,拦截ctrl + c

SIGSTOP,不可忽略的暂停

SIGTSTP,暂停

SIGTERM,进程正常结束

SIGKILL,强行杀死进程

问:如何在【powershell进程】结束前,清理删除配置文件,清理数据等?

答:

Register-EngineEvent -SourceIdentifier Powershell.Exiting -Action { Write-Host "此功能支持linux。powershell进程退出了,再见" }

powershell和bash不同。powershell是多线程级别的,一个powershell可以对应多个线程,每个线程中有很多powershell脚本。

因此单个powershell进程退出事件,基本不适用于多个powershell脚本。所以:

问:如何在脚本结束前,清理删除配置文件,清理数据等?

答:

1对于powershell v5。有begin,process,end脚本块。

2对于powershell v7.3。新增了clean {} 脚本块。

99%建议使用clean

手册:搜clean

https://learn.microsoft.com/zh-cn/powershell/scripting/whats-new/what-s-new-in-powershell-73?view=powershell-7.4

问:是否建议用powershell做守护进程?

答:不建议。powershell功能太多,太复杂。内有很多bug。

问:如何让powershell脚本,健壮地长时间运行?

答:

必须让powershell进程,有一个生命周期(1小时,或n小时)。超时则重新fork自身后,结束进程。

powershell进程必须下班换岗,不能搞7x24。因为新上班的任何进程:1都没有内存泄露问题。2不需要考虑此语言的垃圾回收功能是否完善,是否强大。

这个原则不光适用于powershell,还适用于任何语言开发的程序。

问:powershell如何重新读取文件?

答:没必要用【后台进程+SIGHUP】信号。

方法1:每隔n秒,读取某配置文件的最后修改时间,如果时间变了,则读取文件内容即可。

方法2:可以用上述【powershell进程结束前执行代码】方法,让进程在退出时执行【fork一个新powershell进程,并读取某配置文件内容】

问:powershell如何拦截ctrl + c,并做处理?

答:(下述脚本,win-linux测试正常)

[Console]::TreatControlCAsInput = $True # ctrl +c 此时是普通输入,而不是中断

$Host.UI.RawUI.FlushInputBuffer()

Write-Host "10秒钟内,ctrl+c不灵了"

for ($i = 1 ; $i -lt 11; $i++)

{

Write-Host '.' -NoNewline

Start-Sleep -Seconds 1

}

Write-Host "10秒钟已过,ctrl+c又灵了"

$Host.UI.RawUI.FlushInputBuffer()

[Console]::TreatControlCAsInput = $false

for ($i2 = 1 ; $i2 -lt 11; $i2++)

{

Write-Host '.' -NoNewline

Start-Sleep -Seconds 1

}

---【后记】---

如上所述,

powershell拦截ctrl+c,不需要SIGINT信号。

powershell重新读取文件,也没必要用SIGHUP信号。

问: 那么看官你说了,.net能在linux上处理POSIX Signal吗?

答:

我帮你搜了一篇帖子。

https://carpenoctem.dev/blog/posix-signal-handling-in-dotnet-6/

.net6新增了一些处理POSIX Signal的库。powershell是可以运行c#代码的,可以用powershell 运行c#代码,在linux中处理这些信号。

但,我实在看不出,这些信号对于powershell的用途和使用场景。

欢迎留言反馈,及写贴驳斥。