Golang检测系统中断

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

Golang detect system interrupt

问题

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

stdinScanner := bufio.NewScanner(os.Stdin)
fileScanner := bufio.NewScanner(inFile)
for fileScanner.Scan() {
    target := strings.TrimSpace(fileScanner.Text())
    if len(target) > 0 {
        printUtf16("Delete %s?\n", target)
        stdinScanner.Scan()
        if len(stdinScanner.Text()) > 0 {
            fmt.Println("Non empty return not allowed")
            os.Exit(1)
        } else {
            // TROUBLE: Had to sleep here or interrupt does not work
            time.Sleep(100 * time.Millisecond)
            e := os.Remove(target)
            if e != nil {
                panic(e)
            }
            printUtf16("%s deleted\n", target)
        }
    }
}

我有一个名为 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

		stdinScanner := bufio.NewScanner(os.Stdin)
		fileScanner := bufio.NewScanner(inFile)
		for fileScanner.Scan() {
			target := strings.TrimSpace(fileScanner.Text())
			if len(target) > 0 {
				printUtf16("Delete %s?\n", target)
				stdinScanner.Scan()
				if len(stdinScanner.Text()) > 0 {
					fmt.Println("Non empty return not allowed")
					os.Exit(1)
				} else {
					// TROUBLE: Had to sleep here or interrupt does not work
					time.Sleep(100 * time.Millisecond)
					e := os.Remove(target)
					if e != nil {
						panic(e)
					}
					printUtf16("%s deleted\n", target)
				}
			}
		}

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

scanResult := stdinScanner.Scan()
scanError := stdinScanner.Err()
if scanResult && scanError == nil {
	if len(stdinScanner.Text()) > 0 {
		fmt.Println("Non empty return not allowed")
		os.Exit(1)
	} else {
		deleteFunc(target)
	}
} else {
	errString := "None"
	if scanError != nil {
		errString = scanError.Error()
	}
	fmt.Printf("Scanner returns %t, err: %s\n", scanResult, errString)
	os.Exit(1)
}

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:

确定