Golang检测系统中断

huangapple go评论102阅读模式
英文:

Golang detect system interrupt

问题

我写了一个批量删除文件的实用程序,代码如下:

  1. stdinScanner := bufio.NewScanner(os.Stdin)
  2. fileScanner := bufio.NewScanner(inFile)
  3. for fileScanner.Scan() {
  4. target := strings.TrimSpace(fileScanner.Text())
  5. if len(target) > 0 {
  6. printUtf16("Delete %s?\n", target)
  7. stdinScanner.Scan()
  8. if len(stdinScanner.Text()) > 0 {
  9. fmt.Println("Non empty return not allowed")
  10. os.Exit(1)
  11. } else {
  12. // TROUBLE: Had to sleep here or interrupt does not work
  13. time.Sleep(100 * time.Millisecond)
  14. e := os.Remove(target)
  15. if e != nil {
  16. panic(e)
  17. }
  18. printUtf16("%s deleted\n", target)
  19. }
  20. }
  21. }

我有一个名为 inFile 的文件,其中列出了我想要删除的文件列表。对于每个要删除的文件,我会提示自己以确保操作正确。只有当我输入空输出时,程序才会删除文件并继续处理下一个文件。

现在请注意代码中非常丑陋的 time.Sleep。我注意到,如果我没有插入这个 time.Sleep,当我按下 ctrl+c 时,应用程序的行为会出现意外情况。似乎在按下 ctrl+c 后,stdinScanner.Scan() 会返回 false,没有错误,并且 stdinScanner.Text() 会为空,就像我在输入空内容时所期望的那样。在应用程序被中断并退出之前,我被提示的文件将被删除。

我注意到添加这个 time.Sleep 可以让应用程序有足够的时间退出,并防止当前文件被删除。然而,我真的不喜欢这个解决方案。我想知道是否有一个函数可以调用,而不是使用 time.Sleep,来检查应用程序当前是否正在处理键盘中断,如果是的话,我们就不删除当前文件。

英文:

I wrote an utility to batch delete files as followed

  1. stdinScanner := bufio.NewScanner(os.Stdin)
  2. fileScanner := bufio.NewScanner(inFile)
  3. for fileScanner.Scan() {
  4. target := strings.TrimSpace(fileScanner.Text())
  5. if len(target) > 0 {
  6. printUtf16("Delete %s?\n", target)
  7. stdinScanner.Scan()
  8. if len(stdinScanner.Text()) > 0 {
  9. fmt.Println("Non empty return not allowed")
  10. os.Exit(1)
  11. } else {
  12. // TROUBLE: Had to sleep here or interrupt does not work
  13. time.Sleep(100 * time.Millisecond)
  14. e := os.Remove(target)
  15. if e != nil {
  16. panic(e)
  17. }
  18. printUtf16("%s deleted\n", target)
  19. }
  20. }
  21. }

I have an inFile that specifies a list of files I want to delete. For every file to delete, I prompt myself just to be sure. Only if I enter empty output would the program delete the file and proceed to the next file.

Now note the very ugly time.Sleep in this middle of the code. I have noticed that if I did not insert that time.Sleep the application behaves unexpectedly when I press ctrl+c. Seems like after ctrl+c is pressed stdinScanner.Scan() would return false and no error and stdinScanner.Text() would be empty just as I expected when an empty input is entered. The file that I was prompted for would be deleted before the application is interrupted and quits.

I have noticed that adding this time.Sleep allows the application more than sufficient time to exit and prevent the current file to be deleted. However I really dislike this solution. Just asking if there is a function I can call instead of the time.Sleep to check if the application is currently processing a keyboard interrupt and if so we don't delete the current file?

答案1

得分: 0

感谢Volker和Cerise的回复
答案其实很简单。真不敢相信我竟然忽略了它。我们只需要在继续之前检查扫描器的返回值和错误。

scanResult := stdinScanner.Scan()
scanError := stdinScanner.Err()
if scanResult && scanError == nil {
if len(stdinScanner.Text()) > 0 {
fmt.Println("不允许返回非空值")
os.Exit(1)
} else {
deleteFunc(target)
}
} else {
errString := "无"
if scanError != nil {
errString = scanError.Error()
}
fmt.Printf("扫描器返回值为 %t,错误信息:%s\n", scanResult, errString)
os.Exit(1)
}

英文:

Thanks Volker and Cerise for the response
The answer turns out is quite simple. Can't believe I overlooked it. We just need to check scanner's return and err before proceeding

  1. scanResult := stdinScanner.Scan()
  2. scanError := stdinScanner.Err()
  3. if scanResult && scanError == nil {
  4. if len(stdinScanner.Text()) > 0 {
  5. fmt.Println("Non empty return not allowed")
  6. os.Exit(1)
  7. } else {
  8. deleteFunc(target)
  9. }
  10. } else {
  11. errString := "None"
  12. if scanError != nil {
  13. errString = scanError.Error()
  14. }
  15. fmt.Printf("Scanner returns %t, err: %s\n", scanResult, errString)
  16. os.Exit(1)
  17. }

huangapple
  • 本文由 发表于 2022年9月23日 14:58:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/73824019.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定