Truco una aplicación para pensar que su stdout es una terminal, no una tubería

Estoy tratando de hacer lo opuesto a

Detecta si stdin es un terminal o una tubería?

Estoy ejecutando una aplicación que está cambiando su formato de salida porque detecta una tubería en stdout, y quiero que piense que es una terminal interactiva para que obtenga el mismo resultado al redireccionar.

Estaba pensando que envolverlo en un script expect o usar un proc_open() en PHP lo haría, pero no es así.

¿Alguna idea por ahí?

Aha!

El comando de script hace lo que queremos …

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

¡Hace el truco!

Basado en la solución de Chris , se me ocurrió la siguiente pequeña función auxiliar:

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

El printf aspecto peculiar es necesario para expandir correctamente los argumentos del script en $@ mientras se protegen las partes posiblemente citadas del comando (ver ejemplo a continuación).

Uso:

 faketty   

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 

La secuencia de comandos de unbuffer que viene con Expect debe manejar esto bien. De lo contrario, la aplicación puede estar buscando algo diferente a lo que está conectada su salida, por ej. en qué se establece la variable de entorno TERM.

Refiriéndose a la respuesta anterior, en Mac OS X, “script” se puede usar de la siguiente manera …

 script -q /dev/null commands... 

Pero, como puede cambiar el código de retorno de “\ n” a “\ r \ n”, necesitaba ejecutar esto.

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

Si hay algún conducto entre estos comandos, debe vaciar el stdout. por ejemplo:

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

Donde esté instalado Python,

 echo fakepassword | python -c 'import pty, sys; pty.spawn(sys.argv[1:])' ssh 

No sé si es factible desde PHP, pero si realmente necesita que el proceso hijo vea un TTY, puede crear un PTY .

Cª:

 #include  #include  #include  #include  #include  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 */ } 

Sin embargo, en realidad tenía la impresión de que expect que sí creara un HTP.

Demasiado nuevo para comentar la respuesta específica, pero pensé que haría un seguimiento de la función faketty publicada por ingomueller-net anteriormente, ya que recientemente me ayudó.

Descubrí que esto creaba un archivo de typescript que no quería / necesitaba, así que agregué / dev / null como el archivo de destino del script:

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

¡También hay un pequeño progtwig incluido en el código de muestra del libro “Progtwigción avanzada en el entorno UNIX, segunda edición”!

A continuación se detalla cómo comstackr pty en Mac OS X:

http://codesnippets.joyent.com/posts/show/8786