Похоже, это связано с тем, как MacOS переводит процессы в режим ожидания при блокировке экрана. Это заставляет дочерний процесс osasscript
никогда не завершать выполнение и блокировать цикл for.
Одна вещь, которую вы можете сделать, это запустить команду с контекстом тайм-аута. Я пытался, и это работает. Выполнение будет возобновлено, когда экран разблокирован и истечет время ожидания.
Пример:
package main
import (
"context"
"fmt"
"os/exec"
"time"
)
func main() {
for {
time.Sleep(time.Second * 5)
// run your command with a timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
cmd := exec.CommandContext(
ctx,
"/usr/bin/osascript",
"-e",
`display dialog "hello" with title "hello"`,
)
err := cmd.Run()
if err != nil {
fmt.Println(err)
}
// don't forget to cancel your context to avoid context leak
cancel()
}
}
В качестве альтернативы, если вам не нужен тайм-аут, вы можете проверить, заблокирован ли экран, прежде чем пытаться вызвать диалоговое окно дисплея.
package main
import (
"context"
"fmt"
"os"
"os/exec"
"strings"
"time"
)
func main() {
for {
time.Sleep(time.Second * 5)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
cmd := exec.CommandContext(
ctx,
"python",
"-c",
"import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); print d",
)
var err error
var b []byte
if b, err = cmd.CombinedOutput(); err != nil {
cancel()
continue
}
cancel()
// if screen is not locked
if !strings.Contains(string(b), "CGSSessionScreenIsLocked = 1") {
cmd = exec.Command(
"/usr/bin/osascript",
"-e",
"display dialog \"Hello\"",
)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
fmt.Println("err: ", err)
}
}
}
}