I want to run a program's output through a pipe, but it apparently behaves differently when it detects stdout
is not an interactive shell.
How can I trick it into writing through the pipe just as it would in regular circumstances?
I assume that the program will call the glibc function isatty()
to check whether stdout is a terminal or not. That's common for programs which use colorized output on terminals or other features of an ANSI terminal like cursor positioning or line erasing / redrawing.
You can trick the program using the LD_PRELOAD environment variable. LD_PRELOAD is handled by the ELF linker and tells that a dynamic library should be loaded before all others. Using this feature it is possible to override library functions, in your case the glibc function isatty()
. You can follow this article for example.
I've prepared an example for you:
First create the file libisatty.c:
/**
* Overrides the glibc function. Will always return true.
*
* Note: Although this should be ok for most applications it can
* lead to unwanted side effects. It depends on the question
* why the programm calls isatty()
*/
int isatty(int param) {
return 1;
}
and compile it as a shared lib:
gcc -shared -o libisatty.so libisatty.c
It should build fine.
Now it's time to test the library. :) I've used the command ls --color=auto
for tests. ls
calls isatty()
to decide whether it should colorize it's output or not. If the output is redirected to a file or a pipe it won't be colorized. You can test this easily using the following commands:
ls --color=auto # should give you colorized output
ls --color=auto | cat # will give you monochrome output
Now we'll try the second command again using the LD_PRELOAD environment var:
LD_PRELOAD=./libisatty.so ls --color=auto | cat
You should see colorized output.
btw cool usename: uʍop ǝpısdn !!:D
expect
is a good program to do that – BeniBelascript
program for that purpose: stackoverflow.com/a/1402389/516188 – Emmanuel Touzery