Ctrl C による Golang の exec.Command の中断を防ぐ
exec.Command を使用してコマンドを実行する場合、潜在的な可能性を認識することが重要ですCtrl C 割り込みの場合、たとえ signal.Notify がそのようなシグナルを傍受するために利用されていたとしても。この問題は、次の例で確認できます。
package main import ( "log" "os" "os/exec" "os/signal" "syscall" ) func sleep() { log.Println("Sleep start") cmd := exec.Command("sleep", "60") cmd.Run() log.Println("Sleep stop") } func main() { var doneChannel = make(chan bool) go sleep() c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) signal.Notify(c, syscall.SIGTERM) go func() { <-c log.Println("Receved Ctrl + C") }() <-doneChannel }
プログラムの実行中に Ctrl C を押すと、メイン プログラムが実行を続けているにもかかわらず、「スリープ」コマンドが中断されたことが出力に示されます。
2015/10/16 10:05:50 Sleep start ^C2015/10/16 10:05:52 Receved Ctrl + C 2015/10/16 10:05:52 Sleep stop
この問題を解決する鍵は、Ctrl C が押されたときにシェルがプロセス グループ全体に信号を送ることを認識することにあります。この動作は、syscall.SysProcAttr:
cmd := exec.Command("sleep", "60") cmd.SysProcAttr = &syscall.SysProcAttr{ Setpgid: true, }
の Setpgid フィールドと Pgid フィールドを使用して、独自のプロセス グループでコマンドを開始することで防ぐことができます。この変更を組み込むことで、「スリープ」コマンドが次のコマンドによって中断されなくなります。 Ctrl C を押して、独立して実行を継続できるようにします。
以上がGo で Ctrl C が「exec.Command」を中断しないようにするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。