cmd.Run () навсегда зависает в golang на Macos, когда экран заблокирован / выключен

ОБНОВЛЕНО

Я принял во внимание комментарии и согласился. Eval следует избегать.

Доступ к свойствам корня в объекте легко достигается с помощью obj[variable], но получение вложенных усложняет ситуацию.

Пример

// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);

// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);

Lodash get может использоваться по-разному, вот ссылка на документацию lodash.get

2
задан sgon00 24 March 2019 в 10:39
поделиться

1 ответ

Похоже, это связано с тем, как 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)
            }
        }
    }
}
0
ответ дан François P. 24 March 2019 в 10:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: