Gab*_*iel 1 exit-code go sigint
为什么下面的空程序在 Linux 上以 130 退出Ctrl(C这是我怀疑的,因为我的 shellbash将 SIGINT 包装为 130 (128+2)。
在使用Git Bash ( )的 Windows 上git-bash.exe,我得到退出代码 2。
package main
func main() {
for {
}
}
Run Code Online (Sandbox Code Playgroud)
这是 Go 在 Windows 上的行为还是git-bash.exe?因为我2内部需要退出代码,所以我需要使用signal包来包装它吗?
嗯,它有两重。
\n一方面,正如@Flimzy 指出的那样,它是 shell 的干预。
\n另一方面,他的言论中缺少的是为什么会发生这种情况。
\n同样,解释有两个方面:
SIGINT更新Windows 中的行为。
\n让我们首先提供一个快速的情况说明书:
\n现在让我们更深入地挖掘一下。
\nUnix 诞生时没有任何 GUI 的概念,用户将使用硬件终端与 Unix 系统交互。\n为了支持它们,类 Unix 操作系统的内核实现了特殊的标准化方式,使终端感知程序与系统交互;如果您“想”深入研究技术细节,我强烈建议您阅读“TTY 揭秘”文章。
\n这种方法的两个更重要的亮点是:
SIGINTUnix信号。后者特别令人感兴趣。您可以stty -a在 Linux 系统的终端窗口中运行;在大量的输出中,您会看到类似的内容,intr = ^C; quit = ^\\;这意味着Ctrl-C发送交互主动注意 ( ) 信号并且-发送(是的,“SIGINT”中的“INT”并不代表“中断”\xe2\x80\x94,与一种流行的信念)。\n您几乎可以随意重新分配这些组合键(尽管按照许多软件所期望的方式进行映射并按照它们通常的方式进行映射并且不将自己的操作分配给这些手势并不是明智之举\xe2\ x80\x94 理所当然地期望无法真正收到它们。SIGINTCtrl\\SIGQUIT^C^\\
现在回到Windows。
\n在 Windows 上,没有终端子系统,也没有信号。\nWindows 上的控制台窗口是提供与旧 MS-DOS 系统兼容性所需的人工制品,情况如下:Ctrl-Break会触发通常处理的硬件中断由操作系统,并且Ctrl-C可以明确启用以执行相同的操作。Windows 上控制台模拟的实现仔细地模拟了这种行为,但由于 Windows 没有类似 Unix 的信号,因此这些键盘组合的处理方式有所不同\xe2\x80\x94,但效果大致相同:
\n\n每个控制台进程都有自己的应用程序定义的处理和信号
\nHandlerRoutine函数列表。当用户关闭控制台、注销或关闭系统时,处理程序函数还处理系统生成的信号。最初,每个进程的处理程序列表仅包含调用该函数的默认处理程序函数。CTRL+CCTRL+BREAKExitProcess
这一切对 Go 意味着什么?
\n让我们首先看一下文档:
\n\n\n\n
~$ GOOS=windows go doc os.InterruptRun Code Online (Sandbox Code Playgroud)\npackage os // import "os"\n\nvar (\n Interrupt Signal = syscall.SIGINT\n Kill Signal = syscall.SIGKILL\n)\n所有系统上 os 包中保证存在的唯一信号值是
\nos.Interrupt(向进程发送中断)和os.Kill(强制进程退出)。在 Windows 上,未实现发送os.Interrupt到进程;os.Process.Signal它将返回错误而不是发送信号。
因此,在 Windows 上运行的 Go 程序中,您可以处理这两个“信号”\xe2\x80\x94,即使它们并未真正实现为信号。
\n现在让我们开始解释退出代码的差异。
\n正如您现在所知,Ctrl-C当程序在类 Unix 系统上的终端仿真器窗口中运行时按 将使终端子系统向进程发送实际SIGINT信号。\n如果未显式处理此信号,则进程会被操作系统(默认信号处理就是这样)。\nshell 注意到它生成的进程突然死亡,收集其退出代码并向其添加 128(因为它不希望它以这种方式死亡) 。
\n在 Windows 上,点击Ctrl-C使进程执行系统ExitProcess调用,从 shell 进程的角度来看,这看起来像正常的进程退出:它无法区分此退出与进程os.Exit(0)显式调用时发生的退出。
| 归档时间: |
|
| 查看次数: |
5163 次 |
| 最近记录: |