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的用途和使用场景。
欢迎留言反馈,及写贴驳斥。