Несколько аргументов в Gio.Subprocess - PullRequest
1 голос
/ 10 апреля 2020

Я сейчас разрабатываю свое первое расширение gnome-shell. В расширении я хочу выполнить простую команду оболочки и впоследствии использовать вывод, для которого я использую Gio.Subprocess, как он используется в этой вики: https://wiki.gnome.org/AndyHolmes/Sandbox/SpawningProcesses

В настоящее время, У меня есть такой аргумент с некоторыми параметрами: «ProgramXYZ -a -b c», который я передаю в качестве аргумента-вектора argv как ['ProgramXYZ', '- a', '- b c']. Этот случай работает нормально.

Итак, допустим, я хотел бы вызвать две программы и объединить вывод с вашим подходом, например: "ProgramXYZ -a -b c && ProgramB". Мой текущий вывод корректен в обычном терминале, но я не уверен, как передать его в процесс Gio.Sub. Что-то вроде ['ProgramXYZ', '- a', '- b c', '&&', 'ProgramB'] не работает, есть ли способ добиться этого или мне нужно сделать два отдельных вызова?

1 Ответ

1 голос
/ 11 апреля 2020

Извините, мне не удалось завершить sh эту страницу (вот почему она находится в моей песочнице ?).

Вот наша оболочка Promise для запуска подпроцесса:

function execCommand(argv, input = null, cancellable = null) {
    let flags = Gio.SubprocessFlags.STDOUT_PIPE;

    if (input !== null)
        flags |= Gio.SubprocessFlags.STDIN_PIPE;

    let proc = new Gio.Subprocess({
        argv: argv,
        flags: flags
    });
    proc.init(cancellable);

    return new Promise((resolve, reject) => {
        proc.communicate_utf8_async(input, cancellable, (proc, res) => {
            try {
                resolve(proc.communicate_utf8_finish(res)[1]);
            } catch (e) {
                reject(e);
            }
        });
    });
}

Теперь у вас есть два разумных варианта, так как у вас есть хорошая оболочка.

Я бы предпочел эту опцию сам, потому что, если я запускаю последовательные процессы, я, вероятно, хочу знать, какой сбой произошел, в чем была ошибка, и скоро. Я действительно не стал бы беспокоиться о дополнительных затратах, так как второй процесс выполняется только в том случае, если первый завершился успешно, и в этот момент первый будет подвергнут сборке мусора.

async function dualCall() {
    try {
        let stdout1 = await execCommand(['ProgramXYZ', '-a', '-bc']);
        let stdout2 = await execCommand(['ProgramB']);
    } catch (e) {
        logError(e);
    }
}

С другой стороны, ничто не мешает вы от запуска суб-оболочки, если вы действительно хотите делать оболочку. В конечном итоге вы просто переносите такое же поведение в оболочку, однако:

async function shellCall() {
    try {
        let stdout = await execCommand([
            '/bin/sh',
            '-c',
            'ProgramXYZ -a -bc && ProgramB'
        ]);
    } catch (e) {
        logError(e);
    }
}
...