187 votes

Comment faire croire à une application que sa sortie d'écran est un terminal et non un tuyau ?

J'essaie de faire le contraire de " Détecter si stdin est un terminal ou un tuyau ? ".

J'exécute une application qui change son format de sortie parce qu'elle détecte un pipe sur STDOUT, et je veux qu'elle pense qu'il s'agit d'un terminal interactif afin d'obtenir la même sortie lors de la redirection.

Je pensais que l'envelopper dans un expect script ou en utilisant un fichier proc_open() en PHP devrait le faire, mais ce n'est pas le cas.

Des idées ?

195voto

Aha !

Le site script le commandement fait ce que nous voulons...

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

Cela fait l'affaire !

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

77voto

ingomueller.net Points 369

Sur la base de La solution de Chris j'ai créé la petite fonction d'aide suivante :

faketty() {
    script -qfc "$(printf "%q " "$@")" /dev/null
}

L'aspect excentrique printf est nécessaire pour développer correctement les arguments du script en $@ tout en protégeant les parties éventuellement citées de la commande (voir l'exemple ci-dessous).

Utilisation :

faketty <command> <args>

Ejemplo:

$ python -c "import sys; print sys.stdout.isatty()"
True
$ python -c "import sys; print sys.stdout.isatty()" | cat
False
$ faketty python -c "import sys; print sys.stdout.isatty()" | cat
True

31voto

Colin Macleod Points 1181

Le site débuffer script qui vient avec Attendez-vous à devrait gérer cela correctement. Si ce n'est pas le cas, l'application peut regarder autre chose que ce à quoi sa sortie est connectée, par exemple ce à quoi la variable d'environnement TERM est définie.

22voto

Tsuneo Yoshioka Points 702

En référence à la réponse précédente, sous Mac OS X, "script" peut être utilisé comme ci-dessous...

script -q /dev/null commands...

Mais, parce qu'il peut remplacer " \n " avec " \r\n " sur le stdout, vous pouvez aussi avoir besoin de script comme ceci :

script -q /dev/null commands... | perl -pe 's/\r\n/\n/g'

S'il y a du pipe entre ces commandes, vous devez flusher stdout. par exemple :

script -q /dev/null commands... | ruby -ne 'print "....\n";STDOUT.flush' |  perl -pe 's/\r\n/\n/g'

19voto

ephemient Points 87003

Je ne sais pas si c'est faisable en PHP, mais si vous avez vraiment besoin que le processus enfant voit un TTY, vous pouvez créer un objet PTY .

En 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 */
}

En fait, j'avais l'impression que expect crée cependant un PTY.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X