Обманите приложение, думая, что его стандартный вывод - это терминал, а не труба

Я пытаюсь сделать противоположное

Определить, является ли stdin терминалом или каналом?

Я запускаю приложение, которое меняет свой формат вывода потому что он обнаруживает канал в stdout, и я хочу, чтобы он думал, что это интерактивный терминал, поэтому я получаю тот же вывод при перенаправлении.

Я думал, что обернуть его в скрипт expect или использовать proc_open() в PHP, но это не так.

Есть какие-нибудь идеи?

137
задан the Tin Man 18 November 2019 в 21:39
поделиться

3 ответа

Aha!

The script command does what we want...

script --return --quiet -c "[executable string]" /dev/null

Does the trick!

Usage:
 script [options] [file]

Make a typescript of a terminal session.

Options:
 -a, --append                  append the output
 -c, --command <command>       run command rather than interactive shell
 -e, --return                  return exit code of the child process
 -f, --flush                   run flush after each write
     --force                   use output file even when it is a link
 -q, --quiet                   be quiet
 -t[<file>], --timing[=<file>] output timing data to stderr or to FILE
 -h, --help                    display this help
 -V, --version                 display version
167
ответ дан 23 November 2019 в 23:33
поделиться

Сценарий разблокировки , который поставляется с Expect , должен обработать это нормально. В противном случае приложение может смотреть не на то, к чему подключен его вывод, например. значение переменной среды TERM.

20
ответ дан 23 November 2019 в 23:33
поделиться

Я не знаю, возможно ли это с PHP, но если вам действительно нужен дочерний процесс, чтобы видеть TTY, вы можете создать PTY .

В C:

#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
#include <pty.h>

int main(int argc, char **argv) {
    int master;
    struct winsize win = {
        .ws_col = 80, .ws_row = 24,
        .ws_xpixel = 480, .ws_ypixel = 192,
    };
    pid_t child;

    if (argc < 2) {
        printf("Usage: %s cmd [args...]\n", argv[0]);
        exit(EX_USAGE);
    }

    child = forkpty(&master, NULL, NULL, &win);
    if (child == -1) {
        perror("forkpty failed");
        exit(EX_OSERR);
    }
    if (child == 0) {
        execvp(argv[1], argv + 1);
        perror("exec failed");
        exit(EX_OSERR);
    }

    /* now the child is attached to a real pseudo-TTY instead of a pipe,
     * while the parent can use "master" much like a normal pipe */
}

у меня действительно создалось впечатление, что expect сам создает PTY.

16
ответ дан 23 November 2019 в 23:33
поделиться
Другие вопросы по тегам:

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